【问题标题】:SQL Server: how to include count in the select query with where clause?SQL Server:如何在带有 where 子句的选择查询中包含计数?
【发布时间】:2017-02-01 12:13:51
【问题描述】:

假设我有这张桌子:

id     out    flag
---   ---     ---
 1     0       1
 1     1       0
 1     4       0
 2     0       1
 2     2       0
 2     2       0
 3     0       1
 3     2       0
 3     1       0
 3     4       0

我想计算 out=(0, 2, or 4) 的行数,然后显示 flag = 1 的行

基本上: select id, count(where out IN(0,2,4)) as cnt where flag = 1

我想要的输出:

 id  cnt
---  ----
 1     2
 2     3
 3     3

此查询按预期工作,但仅当我没有“where flag = 1”时:

select id,sum(case when out in (0,2,4) then 1 else 0 end) over(partition by id) as cnt
from tablename

有没有办法让我先计算 sum() 并将其存储在列中,然后使用 where 子句过滤掉行?目前发生的情况是先过滤掉行,然后计算 sum(...)。

有什么办法可以改正吗?

【问题讨论】:

  • id =1 的输出应该是 2 吗?
  • 我同意,id=1 应该是 2
  • 刚刚更新!很抱歉造成混乱。
  • 请更新帖子以反映您的真实需求或打开新帖子

标签: sql sql-server tsql


【解决方案1】:

您可以使用 case 表达式仅对具有 out 列的指定值的 id 行求和。

select id,sum(case when out in (0,2,4) then 1 else 0 end) as cnt
from tablename
group by id

编辑:要在求和时包括其他列,请使用sum 窗口函数。

select * from (select id,flag
               ,sum(case when out in (0,2,4) then 1 else 0 end) over(partition by id) as cnt
               --include other columns as required
               from tablename
              ) x 
where flag=1

【讨论】:

  • 我收到“id 在选择列表中无效,因为它既不包含在聚合函数或 GROUP BY 子句中。”错误。我的 select 语句中有多个列,并且将它们全部包含在 GROUP BY 中会使它变得非常复杂。有没有一种方法可以在不使用 groupby 的情况下对 select 语句中的每一列使用您的查询?
  • 这按预期工作!还有一件事——我的查询中还有一个 where 子句,它从表中过滤掉结果。有没有办法我可以先找到 sum() 然后让 where 子句过滤行?创建另一个选择查询并在内部加入它是我唯一的解决方案吗?
  • 请在问题本身中发布您的所有要求。
  • 我刚刚编辑了我的帖子。你能检查一下吗?谢谢!
【解决方案2】:
select      id,count(*) as cnt
from        tablename
where       out in (0,2,4)
group by    id

【讨论】:

    【解决方案3】:

    请数数0,2,4 OUT。然后使用Inner Join 或使用相关子查询过滤它们

    架构:

    CREATE TABLE #TAB (ID  INT,   OUT_VALUE INT,    FLAG INT)
    
    INSERT INTO #TAB
    SELECT 1,  0, 1
    UNION ALL
    SELECT  1,  1, 0
    UNION ALL
    SELECT  1,  4, 0
    UNION ALL
    SELECT  2,  0, 1
    UNION ALL
    SELECT  2,  2, 0
    UNION ALL
    SELECT  2,  2, 0
    UNION ALL
    SELECT  3,  0, 1
    UNION ALL
    SELECT  3,  2, 0
    UNION ALL
    SELECT  3,  1, 0
    UNION ALL
    SELECT  3,  4, 0
    UNION ALL
    SELECT  4,  4, 0
    

    现在做如下选择

    内部联接

    SELECT T1.ID,COUNT(1) C
    FROM #TAB T1
    INNER JOIN 
    (
            SELECT DISTINCT ID FROM #TAB WHERE FLAG = 1
    )FLAGS ON T1.ID = FLAGS.ID
     WHERE T1.OUT_VALUE IN (0,2,4)
    GROUP BY T1.ID
    

    相关子查询

    SELECT ID, C  FROM (
    SELECT T1.ID
    ,COUNT(1) C
    ,(
            SELECT DISTINCT ID
            FROM #TAB T2
            WHERE T1.ID = T2.ID
                AND T2.FLAG = 1
            ) FLAG
    
    
    FROM #TAB T1 WHERE T1.OUT_VALUE IN (0,2,4)
    GROUP BY T1.ID
    
    )A
    WHERE A.FLAG IS NOT NULL
    

    结果是

    +----+---+
    | ID | C |
    +----+---+
    |  1 | 2 |
    |  2 | 3 |
    |  3 | 3 |
    +----+---+
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-30
      • 2011-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-27
      相关资源
      最近更新 更多