Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 正在返回计数为0的列_Sql_Sql Server_Tsql - Fatal编程技术网

Sql 正在返回计数为0的列

Sql 正在返回计数为0的列,sql,sql-server,tsql,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 =

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

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;
这将返回结果:

但是,我也希望能够返回
今日计数
等于0的状态(即,无论
今日计数
,都应返回id包含在
@StatusIds
中的任何状态)

我曾尝试与一些工会/会员/CTE打交道,但我无法完全让它发挥作用。我不太喜欢SQL,所以不确定还能提供什么有用的东西


谢谢

您可以使用以下函数为您的状态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
现在可以将其用作一个表,您可以将其保留到该表中

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

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

您可以使用以下函数为您的状态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
现在可以将其用作一个表,您可以将其保留到该表中

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

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

如果您想拥有TableC中的所有记录,您需要将所有其他表左键连接到它,而不是将它左键连接到其他表。另外,最好将从
@StatusIds
中创建的筛选表
内部联接
,而不是通过子句中的
应用它。试试这个:

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;

如果您想拥有TableC中的所有记录,您需要将所有其他表左键连接到它,而不是将它左键连接到其他表。另外,最好将从
@StatusIds
中创建的筛选表
内部联接
,而不是通过
子句中的
应用它。试试这个:

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;
请尝试以下方法:

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;
请尝试以下方法:

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;

它未经测试,但请尝试一下:

;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

它未经测试,但请尝试一下:

;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


对于
@StatusIds
,哪个表中没有相应的记录?您已经在进行外部联接,因此应该没有问题,除非是导致记录被排除的
TableA
,在这种情况下,您需要在联接中对表重新排序。注意:
(ILDP.CreatedByDepartmentId=@DepartmentId或@DepartmentId为NULL)
可以写成
(ILDP.CreatedByDepartmentId=IsNull)(@DepartmentId,ILDP.CreatedByDepartmentId)
@shadow我不建议这样做,它会稍微慢一点performance@t-clausen.dk非常正确!刚刚在一个包含303.423行的表上进行了测试。with-IsNull结果在~10“中返回,with-or-xxx在~3”中为null。谢谢朋友。哪个表中没有
@StatusIds
的相应记录?您已经在外部联接,因此应该可以,除非是
TableA
导致记录被排除,在这种情况下,您需要在联接中对表重新排序。注意:
(ILDP.CreatedByDepartmentId=@DepartmentId或@DepartmentId为NULL)
可以写成
(ILDP.CreatedByDepartmentId=IsNull(@DepartmentId,ILDP.CreatedByDepartmentId)
@shadow我不建议这样做,它会稍微慢一点performance@t-clausen.dk非常正确!刚刚在一个包含303.423行的表上进行了测试。在~10“中返回IsNull结果,在~3”中返回with或xxx为null。感谢朋友。我相信他们已经在
dbo.StringAsIntTable
name.:-)下使用了此函数啊,是的,错过了。谢谢。我相信他们已经在
dbo.StringAsIntTable
name.:-)下使用了这个函数。啊,是的,错过了。谢谢。你不能有一个左连接并在WHERE子句中为该连接的表设置一个条件。它取消左连接,使其成为一个内部连接(除非@DepartmentId为NULL)@t-clausen.dk请注意,这个条件出现在
ON
子句中。根本没有
WHERE
子句。我不知道我是怎么误解的,我的道歉。不过还有一些其他问题。COUNT(ILDP,*)无效,nvarchar状态ID中的重复项将导致重复data@t-clausen.dk您是对的。谢谢。添加到答案中。您不能有左连接并在WHERE子句中为该连接表设置条件。它会取消左连接,使其成为内部连接(当@DepartmentId为NULL时除外)@t-clausen.dk请注意,这个条件出现在
ON
子句中。根本没有
WHERE
子句。我不知道我是怎么误解的,我的道歉。不过还有一些其他问题。COUNT(ILDP,*)无效,nvarchar状态ID中的重复项将导致重复data@t-clausen.dk你说得对。谢谢。添加到答案中。CTE是个好主意,但我相信它仍然必须在
From
Join
子句中明确提到。@Y.B.它与table
dbo.TableB
连接。而不是在e xxx in(select..)
。正如@Y.B.正确地说的那样,如果不引用CTE中的列,就不能像使用普通表(FROM或JOIN)一样引用CTE中的列@t-clausen.dk Jesusss…现在我看到了问题所在。真是个蠢货!谢谢各位。我会在脚本中更正它。@shadow-Cte筛选将被
LEFT JOIN
禁用。正如@t-clausen.dk之前对我的答案所评论的那样,@statusID中可能存在重复项,这些重复项在原始解决方案中没有效果,但在
JOIN
。CTE是个好主意,但我相信它仍然必须在
From
JOIN
子句中明确提到。@Y.B.它与table
dbo.TableB
连接。而不是使用
where xxx in(选择..)
。正如@Y.B.正确地说的,如果不引用CTE中的列,就不能像使用普通表(FROM或JOIN)一样引用它@t-clausen.dk Jesusss…现在我看到了问题所在。真是个蠢货!谢谢各位。我会在脚本中更正它。@shadow-Cte筛选将被
LEFT JOIN
禁用。正如@t-clausen.dk之前对我的答案所评论的那样,@statusID中可能存在重复项,这些重复项在原始解决方案中没有效果,但在
JOIN
@Y.B.你完全正确,这一点已经得到纠正,我很高兴ashamed@Y.B.你完全正确,这已经纠正了,我感到羞愧