返回计数为0的列

时间:2016-01-08 09:16:52

标签: sql sql-server tsql

我有一个查询,根据他们的部门和状态查找文档列表。

DECLARE @StatusIds NVARCHAR(MAX) = '1,2,3,4,5';
DECLARE @DepartmentId NVARCHAR(2) = 'IT';

SELECT ILDPST.name,
       COUNT(*) AS TodayCount
FROM dbo.TableA ILDP
LEFT JOIN dbo.TableB ILDPS ON ILDPS.IntranetLoanDealPreStateId = ILDP.IntranetLoanDealPreStateId
LEFT JOIN dbo.TableC ILDPST ON ILDPST.IntranetLoanDealPreStateTypeId = ILDPS.CurrentStateTypeId
WHERE (ILDP.CreatedByDepartmentId = @DepartmentId OR @DepartmentId IS NULL)
    AND ILDPS.CurrentStateTypeId IN (
        SELECT value
        FROM dbo.StringAsIntTable(@StatusIds)
    )
GROUP BY ILDPST.name;

返回结果:

enter image description here

但是,我还希望能够返回TodayCount等于0的状态(即,@StatusIds中包含id的任何状态都应该返回,而不管{{1} }})。

我已经尝试搞乱一些工会/联盟/ ctes,但我无法让它工作。我不是一个SQL人员,所以不确定提供什么可能有用。

谢谢!

4 个答案:

答案 0 :(得分:3)

如果你想拥有TableC中的所有记录,你需要将所有其他表连接到它,而不是将它连接到其他表。此外,您INNER JOIN创建的过滤表最好@StatusIds,而不是通过IN子句应用它。试试这个:

DECLARE @StatusIds NVARCHAR(MAX) = '1,2,3,4,5';
DECLARE @DepartmentId NVARCHAR(2) = 'IT';

SELECT ILDPST.Name, COUNT(ILDP.IntranetLoanDealPreStateId) AS TodayCount
FROM (SELECT DISTINCT value FROM dbo.StringAsIntTable(@StatusIds)) StatusIds
INNER JOIN dbo.TableC ILDPST
  ON ILDPST.IntranetLoanDealPreStateTypeId = StatusIds.value
LEFT JOIN dbo.TableB ILDPS
  ON ILDPS.CurrentStateTypeId = ILDPST.IntranetLoanDealPreStateTypeId
LEFT JOIN dbo.TableA ILDP
  ON ILDP.IntranetLoanDealPreStateId = ILDPS.IntranetLoanDealPreStateId
 AND (ILDP.CreatedByDepartmentId = @DepartmentId OR @DepartmentId IS NULL)
GROUP BY ILDPST.Name;

答案 1 :(得分:2)

请改为尝试:

DECLARE @StatusIds NVARCHAR(MAX) = '1,2,3,4,5';
DECLARE @DepartmentId NVARCHAR(2) = 'IT';

SELECT ILDPST.name,
       COUNT(ILDP.IntranetLoanDealPreStateId) AS TodayCount
FROM 
  dbo.TableC ILDPST 
  LEFT JOIN
    dbo.TableB ILDPS ON ILDPST.IntranetLoanDealPreStateTypeId = ILDPS.CurrentStateTypeId
  LEFT JOIN 
    dbo.TableA ILDP ON ILDPS.IntranetLoanDealPreStateId = ILDP.IntranetLoanDealPreStateId
  AND (ILDP.CreatedByDepartmentId = @DepartmentId OR @DepartmentId IS NULL)
WHERE 
    ILDPST.IntranetLoanDealPreStateTypeId
    IN (
         SELECT value
         FROM dbo.StringAsIntTable(@StatusIds)
       )
GROUP BY ILDPST.name;

答案 2 :(得分:0)

您可以使用以下函数为状态ID创建表值。

CREATE FUNCTION [dbo].[SplitString] 
(
    @myString varchar(max),
    @deliminator varchar(2)
)
RETURNS 
@ReturnTable TABLE 
(
    [Part] [varchar](max) NULL
)
AS
BEGIN
        Declare @iSpaces int
        Declare @part varchar(max)

        --initialize spaces
        Select @iSpaces = charindex(@deliminator,@myString,0)
        While @iSpaces > 0

        Begin
            Select @part = substring(@myString,0,charindex(@deliminator,@myString,0))

            Insert Into @ReturnTable(Part)
            Select @part

    Select @myString = substring(@mystring,charindex(@deliminator,@myString,0)+ len(@deliminator),len(@myString) - charindex(' ',@myString,0))


            Select @iSpaces = charindex(@deliminator,@myString,0)
        end

        If len(@myString) > 0
            Insert Into @ReturnTable
            Select @myString

    RETURN 
END

现在可以将其用作LEFT JOIN到的表格。

DECLARE @StatusIds NVARCHAR(MAX) = '1,2,3,4,5';

SELECT * FROM dbo.SplitString(@StatusIds, ',')

答案 3 :(得分:0)

没有经过测试,但试一试:

;With Cte ( Value ) As
( Select Distinct Value From dbo.StringAsIntTable( @StatusIds ) )
Select
    ILDPST.name,
    COUNT(*) AS TodayCount
From
    dbo.TableC              As ILDPST
    Inner Join Cte                      On ( ILDPST.IntranetLoanDealPreStateTypeId = Cte.Value )                                            
    Left Join dbo.TableB    As ILDPS    On ( ILDPST.IntranetLoanDealPreStateTypeId = ILDPS.CurrentStateTypeId )
    Left Join dbo.TableA    As ILDP     On ( ILDPS.IntranetLoanDealPreStateId = ILDP.IntranetLoanDealPreStateId )
                                            And ( ( ILDP.CreatedByDepartmentId = @DepartmentId ) Or ( @DepartmentId Is Null ) ) 
Group By
    ILDPST.name