如果没有找到记录,则分组并返回零

时间:2013-12-30 23:42:24

标签: sql-server sql-server-2008 tsql

我知道有关于这个主题的各种各样的主题。

我正在尝试创建一个返回预定义的记录的查询,如果没有找到任何结果,我想返回Zero。大多数线程建议我们创建一个临时表来存放这个分组数据,但我需要在一个语句中完成它。但是我们可以使用子查询。


这是我原来的代码......

并返回正确的值,但不包含没有票证的分组:

SELECT SC.Service_Company_Code
     , SSPM.Mapping
     , COUNT(T.Service_Ticket_Id) AS 'Ticket_Count'
FROM SV_Service_Ticket T
 INNER JOIN KS_SedonaSync_Problem SSP ON T.Sub_Problem_Id = SSP.Problem_Id
  RIGHT JOIN KS_SedonaSync_Problem_Sub_Mapping SSPM ON SSP.SedonaSync_Problem_Sub_Mapping_Id = SSPM.SedonaSync_Problem_Sub_Mapping_Id 
 RIGHT JOIN SV_Service_Company SC ON T.Service_Company_Id = SC.Service_Company_Id
WHERE SC.Vendor_Id = 1
 AND SC.Inactive = 'N'
 AND SC.Service_Company_Id <> 1
 AND SSPM.Inactive = 'N'
 AND T.Ticket_Status <> 'CL'
GROUP BY SC.Service_Company_Code, SSPM.Mapping
ORDER BY SC.Service_Company_Code, SSPM.Mapping

我修改后的代码......

现在包含一个子查询,它确实显示了正确的分组,并在Ticket表中单独运行而没有链接。但是当链接到票证表时,它不会在没有记录时显示分组。左连接的使用应该在它们不存在时显示空记录。

SELECT Q.Service_Company_Code
     , Q.Mapping
     , COUNT(T.Service_Ticket_Id) AS 'Ticket_Count'
FROM (SELECT SC.Service_Company_Id, SC.Service_Company_Code, SSP.Problem_Id, SSPM.SedonaSync_Problem_Sub_Mapping_Id, SSPM.Mapping
      FROM SV_Service_Company SC
       FULL OUTER JOIN KS_SedonaSync_Problem_Sub_Mapping SSPM ON 1=1
        LEFT JOIN KS_SedonaSync_Problem SSP ON SSPM.SedonaSync_Problem_Sub_Mapping_Id = SSP.SedonaSync_Problem_Sub_Mapping_Id
      WHERE SC.Vendor_Id = 1
       AND SC.Inactive = 'N'
       AND SC.Service_Company_Id <> 1
       AND SSPM.Inactive = 'N'
      ) Q
 LEFT JOIN SV_Service_Ticket T ON T.Sub_Problem_Id = Q.Problem_Id AND T.Service_Company_Id = Q.Service_Company_Id
WHERE T.Ticket_Status <> 'CL'
GROUP BY Q.Service_Company_Code, Q.Mapping 
ORDER BY Q.Service_Company_Code, Q.Mapping 

非常欢迎任何帮助,谢谢你。

Brad Swindell

编辑:这是当前的结果集。

enter image description here

这是所需的结果集。

enter image description here

编辑:感谢Mike M,我找到了一个可行的解决方案!

SELECT SC.Service_Company_Code
     , SSPM.Mapping
     , COUNT(T.Service_Ticket_Id) AS 'Ticket_Count'
FROM SV_Service_Company SC
  CROSS JOIN KS_SedonaSync_Problem SSP
  INNER JOIN KS_SedonaSync_Problem_Sub_Mapping SSPM ON SSP.SedonaSync_Problem_Sub_Mapping_Id = SSPM.SedonaSync_Problem_Sub_Mapping_Id
   AND SC.Vendor_Id = 1
   AND SC.Inactive = 'N'
   AND SC.Service_Company_Id <> 1 
  LEFT JOIN SV_Service_Ticket T ON T.Sub_Problem_Id = SSP.Problem_Id
   AND T.Service_Company_Id = SC.Service_Company_Id
   AND T.Ticket_Status <> 'CL'
WHERE SSPM.Inactive = 'N'
GROUP BY SC.Service_Company_Code, SSPM.Mapping
ORDER BY SC.Service_Company_Code, SSPM.Mapping

3 个答案:

答案 0 :(得分:1)

我不确定它是否会起作用但是可以试一试,因为没有可用的数据所以有点难以准确地看到发生了什么。无论如何要试一试。

SELECT SC.Service_Company_Code
     , SSPM.Mapping
     , COUNT(T.Service_Ticket_Id) AS [Ticket_Count]
FROM  KS_SedonaSync_Problem SSP 
 RIGHT JOIN SV_Service_Ticket T 
 ON T.Sub_Problem_Id = SSP.Problem_Id
 RIGHT JOIN KS_SedonaSync_Problem_Sub_Mapping SSPM 
 ON SSP.SedonaSync_Problem_Sub_Mapping_Id = SSPM.SedonaSync_Problem_Sub_Mapping_Id 
 RIGHT JOIN SV_Service_Company SC 
 ON T.Service_Company_Id = SC.Service_Company_Id
WHERE SC.Vendor_Id = 1
 AND SC.Inactive = 'N'
 AND SC.Service_Company_Id <> 1
 AND SSPM.Inactive = 'N'
 AND T.Ticket_Status <> 'CL'
GROUP BY SC.Service_Company_Code, SSPM.Mapping
ORDER BY SC.Service_Company_Code, SSPM.Mapping

答案 1 :(得分:1)

您是否尝试将WHERE子句中的最后一位移动到连接条件中? NULL不=或&lt;&gt;什么:)

所以

T.Ticket_Status <> 'CL'

可能无法拉出那些有NULL的行。

添加 “和T.Ticket_Status&lt;&gt;'CL'” 作为加入条件中的另一项,

 LEFT JOIN SV_Service_Ticket T ON T.Sub_Problem_Id = Q.Problem_Id AND T.Service_Company_Id = Q.Service_Company_Id and T.Ticket_Status <> 'CL'



所以你看到我们来自哪里,这是我们(和你)想要发生的基本情况。 你确定子查询已经确定了吗?

if object_id('tempdb..#tempItems') is not null
    drop table #tempItems;


create table #tempItems (
        id int primary key
        , category varchar(100)
        , subCategory varchar(100)

    )
;

insert into #tempItems (id, category, subCategory)
values (1, 'First', 'subA');
insert into #tempItems (id, category, subCategory)
values (2, 'First', 'subB');
insert into #tempItems (id, category, subCategory)
values (3, 'Second', 'subA');
insert into #tempItems (id, category, subCategory)
values (4, 'NotFound', 'subNotFound');


---------------------------------------------------------

if object_id('tempdb..#tempCounts') is not null
    drop table #tempCounts;


create table #tempCounts (
        id int primary key
        , itemId int
    )
;

insert into #tempCounts (id, itemId)
values (1, 1);
insert into #tempCounts (id, itemId)
values (2, 2);
insert into #tempCounts (id, itemId)
values (3, 3);
insert into #tempCounts (id, itemId)
values (4, 3);


----------------------------------------------------------





select
    items.category
    ,items.subcategory
    , count(counts.id) as count
from
    #tempItems items
        left join #tempCounts counts on items.id = counts.itemid

group by items.category, items.subcategory
order by items.category, items.subcategory

答案 2 :(得分:1)

如果我正确地阅读了您的SQL,我认为您只需要将where条件移至LEFT JOIN。如果这不能产生预期的结果,你能否设置一个SQL小提琴?

SELECT Q.Service_Company_Code
     , Q.Mapping
     , COUNT(T.Service_Ticket_Id) AS 'Ticket_Count'
FROM (
    SELECT SC.Service_Company_Id, SC.Service_Company_Code, SSP.Problem_Id, SSPM.SedonaSync_Problem_Sub_Mapping_Id, SSPM.Mapping
    FROM SV_Service_Company SC
    CROSS JOIN KS_SedonaSync_Problem_Sub_Mapping SSPM
    LEFT JOIN KS_SedonaSync_Problem SSP ON SSPM.SedonaSync_Problem_Sub_Mapping_Id = SSP.SedonaSync_Problem_Sub_Mapping_Id
    WHERE SC.Vendor_Id = 1
    AND SC.Inactive = 'N'
    AND SC.Service_Company_Id <> 1
    AND SSPM.Inactive = 'N'
) Q
LEFT JOIN SV_Service_Ticket T ON T.Sub_Problem_Id = Q.Problem_Id AND T.Service_Company_Id = Q.Service_Company_Id AND T.Ticket_Status <> 'CL'
GROUP BY Q.Service_Company_Code, Q.Mapping 
ORDER BY Q.Service_Company_Code, Q.Mapping