如何使用空值左连接

时间:2015-03-30 05:49:37

标签: sql tsql sql-server-2012

我正在尝试进行自联接并减去同一列的值。

--sum of all pageviews of circleid 0 of each device category - (sum of all 
--pageviews of circleid <> 0 of each device category)

现有表格 -

PageName    DeviceCategory  FKCircleId  FKGAFilterKeyID PageViews
login       desktop         0            5              10
login       desktop         0            5              20
login       mobile          0            5              5
login       tablet          0            5             15
login       desktop         1            4              2
login       desktop         1            4              2
login       mobile          1            4              3
login       tablet          1            4              4

所需的o / p:

PageName    DeviceCategory  PageViews
login       desktop         26 --(30-4)
login       mobile           2 --(5-3)
login       tablet           11 --(15-4)

但是这个查询给了我空值

PageName DeviceCategory Circle  Total   
Login    desktop    NULL    NULL
Login    mobile     NULL    NULL
Login    tablet     NULL    NULL

CREATE TABLE gadata(PageName varchar(10),DeviceCategory 
varchar(10),FKCircleId int, FKGAFilterKeyID int,PageViews int)
insert into gadata values('login','desktop',0,5,10)
insert into gadata values('login','desktop',0,5,20)
insert into gadata values('login','mobile',0,5,5)
insert into gadata values('login','tablet',0,5,15)
insert into gadata values('login','desktop',1,4,2)
insert into gadata values('login','desktop',1,4,2)
insert into gadata values('login','mobile',1,4,3)
insert into gadata values('login','tablet',1,4,4)

    ;WITH TBL3 AS(      
    SELECT gd.PageName,gd.DeviceCategory,'All' AS Circle,
           SUM(gd.PageViews) AS Total1,gd.FKGAFilterKeyID
    FROM gadata(NOLOCK) gd          
    WHERE gd.FKGAFilterKeyID =5     
    GROUP BY gd.PageName,gd.DeviceCategory,gd.FKGAFilterKeyID
    ),
    TBL4 AS(        
    SELECT gd.PageName,gd.DeviceCategory,'Other' AS t4Circle,
           ISNULL(SUM(gd.PageViews),0) AS Total2,gd.FKGAFilterKeyID
    FROM gadata(NOLOCK) gd      
    WHERE gd.FKGAFilterKeyID <> 5       
    GROUP BY gd.PageName,gd.DeviceCategory,gd.FKGAFilterKeyID
    )
    SELECT t3.PageName,t3.DeviceCategory,t4.t4Circle AS Circle,
           (t3.Total1-t4.Total2) AS Total
    FROM TBL3 t3
    LEFT JOIN TBL4 t4 ON t3.FKGAFilterKeyID = t4.FKGAFilterKeyID 
AND t3.DeviceCategory= t4.DeviceCategory

当我在tbl3&amp;中运行subQueries时单独tbl4,我得到数据。 我哪里错了。

sqlfiddle不能正常工作。我会给小提琴。

3 个答案:

答案 0 :(得分:2)

您正在加入错误的列。还可以使用ISNULL函数,以便在NULL中找不到匹配的行时不获取TBL4

SELECT t3.PageName,t4.t4Circle AS Circle,
       (t3.Total1-ISNULL(t4.Total2, 0)) AS Total
FROM TBL3 t3
LEFT JOIN TBL4 t4 ON t3.PageName = t4.PageName AND t4.DeviceCategory = t3.DeviceCategory

输出:

PageName    Circle  Total
login       Other   26
login       Other   2
login       Other   11

我删除了AccessType列,因为它不在创建脚本中。

编辑:

我也不了解您的逻辑,但如果您的TBL4值不在TBL3中(例如login, windows phone, 1, 10),那么您可以使用{{1 }}:

FULL OUTER JOIN

输出:

insert into gadata values('login','win. phone',1,10,6)

SELECT ISNULL(t3.PageName, t4.PageName) AS PageName,t4.t4Circle AS Circle,
       (ISNULL(t3.Total1, 0)-ISNULL(t4.Total2, 0)) AS Total
FROM TBL3 t3
FULL JOIN TBL4 t4 ON t3.PageName = t4.PageName AND t4.DeviceCategory = t3.DeviceCategory

答案 1 :(得分:1)

而不是有问题的长查询只需使用self join

select tbl1.pagename, tbl1.devicecategory, tbl1.pageviews - tbl2.pageviews
from (select t2.pagename, t2.devicecategory, sum(t2.pageviews) as pageviews
       from gadata t2
       where t2.FKCircleId=0 
       group by t2.pagename, t2.devicecategory) tbl1
join (select t3.pagename, t3.devicecategory, sum(t3.pageviews) as pageviews
       from gadata t3
       where t3.FKCircleId <> 0 
       group by t3.pagename, t3.devicecategory) tbl2
on tbl1.pagename=tbl2.pagename and tbl1.devicecategory=tbl2.devicecategory

输出:

login       desktop         26 
login       mobile           2 
login       tablet           11 

SQLFIDDLE DEMO

答案 2 :(得分:1)

WITH cte1 
AS
(SELECT [PageName],[DeviceCategory],sum([PageViews]) smx
FROM [dbo].[gadata]
WHERE [FKCircleId]=0
GROUP BY [PageName],[DeviceCategory])
,cte2
AS
(SELECT [PageName],[DeviceCategory],sum([PageViews]) smx1
FROM [dbo].[gadata]
WHERE [FKCircleId]!=0
GROUP BY [PageName],[DeviceCategory])
--SELECT * FROM cte1
SELECT c1. [PageName],c1.[DeviceCategory],smx-smx1 as Total
FROM cte2 AS c2 JOIN cte1 AS c1
ON c2.[DeviceCategory]=c1.[DeviceCategory]

enter image description here