【问题标题】:Using HAVING COUNT(column name) NOT working as expected使用 HAVING COUNT(column name) 未按预期工作
【发布时间】:2021-10-04 04:44:22
【问题描述】:

我有 SQL 语句,在 SQL Server 2016 中工作,在下面我从 INNER SELECT UNION ALL 语句中获取记录,在 OUTER SELECT 中,我试图提取那些符合 HAVING COUNT 代码的记录,我的代码没有带回任何记录。
以下是我使用 UNION ALL 的 INNER SELECT 语句中的记录:

LocationSysID LocationName AgentNo RepID RepName Count RN
5 A-MAX 22810 17025 mel 339 1
43 ADV 21371 17025 mel 100 1
43 ADV 21371 17025 mel 0 2
94 ALPINE 21249 17025 mel 64 1
94 ALPINE 21249 17025 mel 0 2
126 AMS 21537 17025 mel 333 1
138 ADV 22812 17025 mel 1180 1

我正在尝试通过 OUTER SELECT 从 COUNT(LocationSysID) > 1 的 INNER select 语句中获取这些记录。这样将返回 LocationSysID 为 43 和 94 的 4 条记录。

任何帮助/指导将不胜感激。谢谢。

这是我的 SQL 代码:

SELECT x.LocationSysID, x.LocationName, x.AgentNo, x.RepID, x.RepName, x.TotalCount, x.RN
FROM (
    SELECT q.LocationSysID, q.LocationName, q.AgentNo, q.RepID, q.RepName, q.QuoteCount as TotalCount, '1' as RN
    FROM #tempYesQuotes q 
    WHERE q.QuoteCount > 0
    --ORDER BY LocationSysID asc;

    UNION ALL

    SELECT p.LocationSysID, p.LocationName, p.AgentNo, p.RepID, p.RepName, p.PolicyCount as TotalCount, '2' as RN
    FROM #tempNoNewPolicies p
    WHERE p.PolicyCount = 0
    --ORDER BY LocationSysID asc, RN asc;
) x
GROUP BY LocationSysID, LocationName, AgentNo, RepID, RepName, TotalCount, RN
HAVING COUNT(LocationSysID) > 1  
ORDER BY LocationSysID asc, RN asc;

【问题讨论】:

  • 您想要的结果不清楚。为什么你写了你想在结果中看到 4 条 LocationSysID 为 43 和 94 的记录?其中两条记录的计数 = 0。为什么您不想看到其他 LocationSysID 的记录,例如 5、126、138?他们的数量超过 1。
  • 我只想要那些 LocationSysID 在结果集中出现超过 1 次的记录。这就是为什么我只想查看 LocationSysID 43 和 94。抱歉,我应该澄清一下。我不在乎那些 LocationSysID 只有一条记录的记录。希望这是有道理的。
  • 好吧,Count 的专栏让我很困惑。我现在明白你不关心这些列中的值。您对行数感兴趣。
  • 正确。我知道 HAVING COUNT 子句会给我那些具有多次列出的指定列的 COUNT 的记录。显然我有一个错误的理解,因此我的帖子的原因。

标签: sql sql-server tsql sql-server-2016


【解决方案1】:

您看到问题中描述的结果的原因是您按所有这些字段分组:

GROUP BY LocationSysID, LocationName, AgentNo, RepID, RepName, TotalCount, RN

TotalCountRN 中的值不一样,所以每组只有一行。因此COUNT() 函数只返回1

因此,如果您只是更改您的GROUP BY 子句并从中删除列TotalCount, RN,您将获得您期望的结果。 但是,使用您拥有的查询结构,您还必须从最终结果集中删除这些列。

我猜你想保留它们。为了实现这一点,我建议使用窗口化的COUNT() OVER() 函数而不是普通的COUNT

我在这里使用 CTE 使查询可读。如果需要,您可以将它们内联到一个大型查询中。不影响性能。

WITH
CTE_Union
AS
(
    SELECT q.LocationSysID, q.LocationName, q.AgentNo, q.RepID, q.RepName, q.QuoteCount as TotalCount, '1' as RN
    FROM #tempYesQuotes q 
    WHERE q.QuoteCount > 0
    --ORDER BY LocationSysID asc;

    UNION ALL

    SELECT p.LocationSysID, p.LocationName, p.AgentNo, p.RepID, p.RepName, p.PolicyCount as TotalCount, '2' as RN
    FROM #tempNoNewPolicies p
    WHERE p.PolicyCount = 0
    --ORDER BY LocationSysID asc, RN asc;
)
,CTE_RowCount
AS
(
    SELECT
        LocationSysID, LocationName, AgentNo, RepID, RepName, TotalCount, RN
        ,COUNT(*) OVER (PARTITION BY LocationSysID) AS LocationCount
    FROM
        CTE_Union
)
SELECT
    LocationSysID, LocationName, AgentNo, RepID, RepName, TotalCount, RN
FROM
    CTE_RowCount
WHERE
    LocationCount > 1
ORDER BY
    LocationSysID asc, RN asc
;

【讨论】:

    【解决方案2】:

    CTE 代替外部选择,帮助您获得一些清晰的图片

    试试下面的

    ;WITH X
    AS
        (
        SELECT q.LocationSysID, q.LocationName, q.AgentNo, q.RepID, q.RepName, q.QuoteCount as TotalCount, '1' as RN
        FROM #tempYesQuotes q 
        WHERE q.QuoteCount > 0
        --ORDER BY LocationSysID asc;
    
        UNION ALL
    
        SELECT p.LocationSysID, p.LocationName, p.AgentNo, p.RepID, p.RepName, p.PolicyCount as TotalCount, '2' as RN
        FROM #tempNoNewPolicies p
        WHERE p.PolicyCount = 0
        --ORDER BY LocationSysID asc, RN asc;
        )
    SELECT x.LocationSysID, x.LocationName, x.AgentNo, x.RepID, x.RepName, x.TotalCount, x.RN
    WHERE X.LocationSysID IN(SELECT X1.LocationSysID FROM X X1 GROUP BY X1.LocationSysID HAVING COUNT(1) > 1)
    ORDER BY X.LocationSysID asc, X.RN asc;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-01
      • 2016-09-22
      • 1970-01-01
      • 1970-01-01
      • 2021-06-04
      • 2015-11-11
      • 2016-09-16
      • 2014-08-13
      相关资源
      最近更新 更多