【问题标题】:SQL Server : how to use countSQL Server:如何使用计数
【发布时间】:2016-04-18 04:42:25
【问题描述】:

我正在使用这个 SQL Server database。我正在为国家/地区定义以下备注

CASE 
    WHEN density_per_sq_km > 1000 THEN 'Overpopulated'
    WHEN density_per_sq_km > 500 THEN 'above average'
    WHEN density_per_sq_km > 250 THEN 'average'
    WHEN density_per_sq_km > 50 THEN 'below average' 
    ELSE 'Underpopulated'
END as remarks

现在我想计算每条评论中有多少个国家。我怎样才能做到这一点?我正在使用以下查询,但它失败了

SELECT 
    COUNT(country) as no_of_countries,
    CASE 
        WHEN density_per_sq_km > 1000 THEN 'Overpopulated'
        WHEN density_per_sq_km > 500 THEN 'above average'
        WHEN density_per_sq_km > 250 THEN 'average'
        WHEN density_per_sq_km > 50 THEN 'below average' 
        ELSE 'Underpopulated'
    END as remarks
FROM 
    countries_by_population 
GROUP BY 
    remarks;

【问题讨论】:

  • 使用COUNT(distinct country)

标签: sql sql-server count case


【解决方案1】:

在 group by 子句中,您不能使用该列别名,请改用 case 表达式

SELECT
      COUNT(country) AS no_of_countries
    , CASE
            WHEN density_per_sq_km > 1000 THEN 'Overpopulated'
            WHEN density_per_sq_km > 500 THEN 'above average'
            WHEN density_per_sq_km > 250 THEN 'average'
            WHEN density_per_sq_km > 50 THEN 'below average'
            ELSE 'Underpopulated'
      END AS remarks
FROM countries_by_population
GROUP BY
      CASE
            WHEN density_per_sq_km > 1000 THEN 'Overpopulated'
            WHEN density_per_sq_km > 500 THEN 'above average'
            WHEN density_per_sq_km > 250 THEN 'average'
            WHEN density_per_sq_km > 50 THEN 'below average'
            ELSE 'Underpopulated'
      END
;

【讨论】:

  • 你能解释一下我可以使用 GROUP BY 或 ORDER BY 中的备注吗
  • 您可以在 ORDER BY 子句中使用别名。 除非使用交叉应用(参见 Evaldas Buinauskas 的回答),否则不能使用 group by 子句,或者您可以使用“派生”表”(见 Jiri Tousek 的回答)。正如我所展示的那样,在重新使用 case 表达式时(根本没有)性能损失。
【解决方案2】:

将带有计算列的查询包装到子查询中可能会帮助您使用该列:

SELECT remarks, COUNT(country) as no_of_countries
FROM (
  SELECT
    CASE 
      WHEN density_per_sq_km > 1000 THEN 'Overpopulated'
      WHEN density_per_sq_km > 500 THEN 'above average'
      WHEN density_per_sq_km > 250 THEN 'average'
      WHEN density_per_sq_km > 50 THEN 'below average' 
      ELSE 'Underpopulated'
    END as remarks,
    country
  FROM countries_by_population
) DT
GROUP BY remarks;

【讨论】:

    【解决方案3】:

    您可以使用CROSS APPLY 为您的列分配别名。

    SELECT T.Remarks, COUNT(*) AS no_of_countries
    FROM countries_by_population AS CBP
    CROSS APPLY (
        SELECT CASE
                WHEN density_per_sq_km > 1000 THEN 'Overpopulated'
                WHEN density_per_sq_km > 500  THEN 'Above average'
                WHEN density_per_sq_km > 250  THEN 'Average'
                WHEN density_per_sq_km > 50   THEN 'Below average'
                ELSE 'Underpopulated'
            END
        ) AS T(Remarks)
    GROUP BY T.Remarks;
    

    这将根据您的密度创建一个列Remarks,以后可以在GROUP BY 中使用。

    Tip: APPLY and Reuse of Column Aliases 文章详细解释了如何使用CROSS APPLY 创建可重用的列别名。

    【讨论】:

    • 这行得通,但我还不熟悉 CROSS APPLY 以及该查询中 T 的使用。我是初学者,正在学习 SQL
    • @Newton 你可以阅读这个问题:stackoverflow.com/questions/9275132/… 还有一个链接解释了如何使用它来创建可以重复使用的别名。这应该是一个很好的起点。
    猜你喜欢
    • 1970-01-01
    • 2016-05-05
    • 2014-07-25
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 2015-04-13
    • 2011-08-06
    • 2019-05-21
    相关资源
    最近更新 更多