SQL仅返回包含数据的行,不返回0的行

SQL仅返回包含数据的行,不返回0的行,sql,tsql,Sql,Tsql,我试图报告有多少项处于特定状态。 我得到的代码只返回有值的行,而不返回没有值的行 SELECT Department ,Status ,count(Department) AS "Number in status" ,convert(VARCHAR, getdate(), 103) AS "Date report ran" FROM [Server name].[xxx].[Database name] WHERE STATUS NOT IN (

我试图报告有多少项处于特定状态。 我得到的代码只返回有值的行,而不返回没有值的行

SELECT Department
       ,Status
       ,count(Department) AS "Number in status" 
       ,convert(VARCHAR, getdate(), 103) AS "Date report ran"
FROM [Server name].[xxx].[Database name]
WHERE STATUS NOT IN (
              'Closed'
              ,'Cancelled'
              )
       AND Department IN (
              'Department name'
              )
GROUP BY Department,Status

ORDER BY CASE 
              WHEN STATUS = 'Open'
                     THEN 1
              WHEN STATUS = 'In Progress'
                     THEN 2
              WHEN STATUS = 'Authorised'
                     THEN 3
              WHEN STATUS = 'Awaiting Auth'
                     THEN 4
              WHEN STATUS = 'Awaiting Collection'
                     THEN 5
              WHEN STATUS = 'Awaiting Delivery'
                     THEN 6
              WHEN STATUS = 'Awaiting Development'
                     THEN 7
              WHEN STATUS = 'Awaiting Engineer'
                     THEN 8
              WHEN STATUS = 'Awaiting Invoice/Credit'
                     THEN 9
              WHEN STATUS = 'Awaiting Quote'
                     THEN 10
              WHEN STATUS = 'Cancelled'
                     THEN 11
              WHEN STATUS = 'Chase End User'
                     THEN 12
              WHEN STATUS = 'Final Chase End User'
                     THEN 13
              WHEN STATUS = 'Closed'
                     THEN 14
              WHEN STATUS = 'Future Requirements'
                     THEN 15
              WHEN STATUS = 'In Test'
                     THEN 16
              WHEN STATUS = 'Next Release'
                     THEN 17
                     WHEN STATUS = 'On Hold'
                     THEN 18
                     WHEN STATUS = 'With End-User'
                     THEN 22
                     WHEN STATUS = 'With IIT'
                     THEN 23
                     WHEN STATUS = 'Processing Via Demand Management'
                     THEN 27
              END;
结果如下所示,但不包括所有其他可能为0的状态:

+-----------------+----------------------------------+----+------------+
|                 |                                  |    |            |
+-----------------+----------------------------------+----+------------+
| Department name | Open                             | 92 | 29/03/2019 |
| Department name | In Progress                      |  9 | 29/03/2019 |
| Department name | Awaiting Development             |  4 | 29/03/2019 |
| Department name | Future Requirements              |  1 | 29/03/2019 |
| Department name | In Test                          |  7 | 29/03/2019 |
| Department name | On Hold                          | 15 | 29/03/2019 |
| Department name | With End-User                    | 28 | 29/03/2019 |
| Department name | With IIT                         |  2 | 29/03/2019 |
| Department name | Processing Via Demand Management |  2 | 29/03/2019 |
+-----------------+----------------------------------+----+------------+

您需要一个状态表,至少包含状态描述和(可能)报告顺序:

CREATE TABLE Statuses (
    Status varchar(30) not null,
    ReportOrder int not null,
    ShowInReport bit not null,
    constraint PK_Statuses (Status)
)
现在,您可以使用
LEFT JOIN
将查询从该表写入另一个未命名表(因为您的查询当前声称查询的是数据库,而不是其
from
子句中的表:

SELECT Department
       ,s.Status
       ,count(Department) AS "Number in status" 
       ,convert(VARCHAR, getdate(), 103) AS "Date report ran"
FROM
    Statuses s
       left join
    unnamedTable t
       on
          s.Status = t.Status
WHERE s.ShowInReport = 1
       AND Department IN (
              'Department name'
              )
GROUP BY Department,s.Status
ORDER BY s.ReportOrder
如果您仍然希望在
0
行的输出中使用部门名称,那么最好也有一个
Departments
表,使用方式与上述非常类似:

...
FROM
    Statuses s
       cross join
    Departments d
       left join
    unnamedTable t
       on
          s.Status = t.Status and
          d.Department = t.Department
...

(您还应该在未命名表和状态之间有一个FK,以确保其中使用的所有状态值都有效)

您需要一个状态表,至少包含状态描述和(可能)报告顺序:

CREATE TABLE Statuses (
    Status varchar(30) not null,
    ReportOrder int not null,
    ShowInReport bit not null,
    constraint PK_Statuses (Status)
)
现在,您可以使用
LEFT JOIN
将查询从该表写入另一个未命名表(因为您的查询当前声称查询的是数据库,而不是其
from
子句中的表:

SELECT Department
       ,s.Status
       ,count(Department) AS "Number in status" 
       ,convert(VARCHAR, getdate(), 103) AS "Date report ran"
FROM
    Statuses s
       left join
    unnamedTable t
       on
          s.Status = t.Status
WHERE s.ShowInReport = 1
       AND Department IN (
              'Department name'
              )
GROUP BY Department,s.Status
ORDER BY s.ReportOrder
如果您仍然希望在
0
行的输出中使用部门名称,那么最好也有一个
Departments
表,使用方式与上述非常类似:

...
FROM
    Statuses s
       cross join
    Departments d
       left join
    unnamedTable t
       on
          s.Status = t.Status and
          d.Department = t.Department
...

(您还应该在未命名表和
状态之间有一个FK,以确保其中使用的所有状态值都有效)

如果您的数据库设计良好,您的状态和部门将被合并到一个单独的表中,并与您的记录合并。因此,您希望执行以下操作,而不是自然合并:

部门X状态->您可以获得所有部门和状态组合 然后在结果表上与记录进行左连接。
然后按部门和状态分组并进行计数。

如果数据库设计良好,则您的状态和部门将被放入一个单独的表中,并与您的记录合并。因此,您希望执行以下操作,而不是自然合并:

部门X状态->您可以获得所有部门和状态组合 然后在结果表上与记录进行左连接。
然后,您可以按部门和状态分组并进行计数。

俗话说“没有行”。输出中的每一行都是由一个或多个输入行组成的组的表示。您可以创建一个具有所有可能状态的表并创建外部联接。俗话说,“没有行”。输出中的每一行都是由一个或多个输入行组成的组的表示。您可以创建一个具有所有可能状态的表并创建外部联接。有关详细信息,请参阅-Damien\u非异信者答案。有关详细信息,请参阅-Damien\u非异信者答案。