【问题标题】:Is there a way to select two counts with different subqueries in one syntax?有没有办法在一种语法中选择具有不同子查询的两个计数?
【发布时间】:2019-04-11 14:10:09
【问题描述】:

基本上我想得到两个计数。第一个计数是记录数。第二个计数是有数据的记录数。这两个计数来自名为调查的表,该表没有所有州名。所以我将它与另一个表 UsState 连接起来以获取所有状态名称。我整理了语法,但出现错误。

SELECT
Name as State,
count (*)from NamrsFrozen2017.Investigation2017 where FiscalYear = 2017 AND StateName in (SELECT distinct StateName FROM [NamrsFrozen2017].[Investigation2017] WHERE (not ReportDate = '' ))[Report Date Records],
count (*) from NamrsFrozen2017.Investigation2017 WHERE FiscalYear = 2017 AND ReportDate != '' AND StateName in (SELECT distinct StateName FROM [NamrsFrozen2017].[Investigation2017] WHERE (not ReportDate = '' ))[Report Date Records with Data]
From
(SELECT DISTINCT Name FROM NamrsFullDw.UsState) s
LEFT JOIN NamrsFrozen2017.Investigation2017 c ON s.Name = c.StateName AND  c.FiscalYear = 2017
  GROUP BY Name
  Order by Name

【问题讨论】:

  • 不要使用COUNT(*),而是将列的名称放在函数之一的括号中。聚合函数不包含 NULL 值。 SELECT COUNT(*),COUNT(I) FROM (VALUES(1),(2),(NULL))V(I); 分别返回 3 和 2。
  • 我不认为我理解您的回复,您能否澄清一下。我在名称和 s @Larnu 上收到错误
  • 好吧,你不能这样做SELECT Name, COUNT(*) FROM... AS {alias}, COUNT(*) FROM...,这没有意义。我们看不到您看到的内容,因此请发布一些示例数据和预期结果(text,不是图片)。
  • 样本数据、所需结果以及对您想要做什么的解释会有所帮助。

标签: sql sql-server


【解决方案1】:

一些相关的子查询会对您有所帮助。它们看起来像内联选择,但使用对内联查询之外的表的引用。像这样:

SELECT 
   Name as State,
   (SELECT COUNT(*) 
    FROM NamrsFrozen2017.Investigation2017 
    --I would think you want to view count of records for the current state, and not ALL states
    -- and not ALL states. So filter like this:
    WHERE FiscalYear = 2017 AND StateName = s.Name -- <-Correlated
    --Don't need a full list, like you had before
    -- (SELECT distinct StateName FROM [NamrsFrozen2017].[Investigation2017] WHERE (not ReportDate = '' ))
   ) AS [Report Date Records],
   (SELECT COUNT(*) 
    FROM NamrsFrozen2017.Investigation2017 
    WHERE FiscalYear = 2017 AND StateName = s.Name -- <- correlated
        AND ReportDate != '' --or maybe ReportDate IS NOT NULL            
    --Don't need to query the full table after correlating this to your FROM clause
    --  in (SELECT distinct StateName FROM [NamrsFrozen2017].[Investigation2017] WHERE (not ReportDate = '' ))
   ) AS [Report Date Records with Data]
FROM
   (SELECT DISTINCT Name FROM NamrsFullDw.UsState) s
   LEFT JOIN NamrsFrozen2017.Investigation2017 c 
        ON s.Name = c.StateName AND c.FiscalYear = 2017
GROUP BY s.Name
ORDER BY s.Name

这可能会得到更多优化,但我不熟悉您的数据,或者不清楚您想用原始查询完成什么。

【讨论】:

    【解决方案2】:

    评论太长了。

    您遇到的语法错误是因为您的内联子查询格式不正确。你不能从COUNT(*)函数开始;它们每个都需要完全形成SELECT 语句。然后每一个都需要用括号括起来。

    您的查询应该是这样的。

    SELECT
      Name AS State
     ,(
        SELECT
          COUNT(*)
        FROM
          NamrsFrozen2017.Investigation2017
        WHERE
          FiscalYear = 2017
          AND StateName IN
              (
                SELECT DISTINCT StateName
                FROM NamrsFrozen2017.Investigation2017
                WHERE ReportDate <> ''
              )
      ) AS [Report Date Records]
     ,(
        SELECT
          COUNT(*)
        FROM
          NamrsFrozen2017.Investigation2017
        WHERE
          FiscalYear = 2017
          AND ReportDate != ''
          AND StateName IN
              (
                SELECT DISTINCT StateName
                FROM NamrsFrozen2017.Investigation2017
                WHERE (NOT ReportDate = '')
              )
      ) AS [Report Date Records with Data]
    FROM
      (SELECT DISTINCT Name FROM NamrsFullDw.UsState) AS s
    LEFT JOIN
      NamrsFrozen2017.Investigation2017 AS c
        ON
        s.Name = c.StateName
          AND c.FiscalYear = 2017
    GROUP BY
      Name
    ORDER BY
      Name;
    

    这里还有一个次要问题,即此查询是否会按照您的预期执行。对于 Larnu 在 cmets 中的观点,聚合函数在不同情况下以不同方式处理 NULL。但是,如果没有要测试的样本数据,我无法判断这个功能版本的查询是否会返回您想要的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-01
      相关资源
      最近更新 更多