sql-server - 将一张表中的 SQL 列分组

标签 sql-server

我目前很难从表中获取正确的值。这是我的 table

注意:Status 列有 3 个可能的值(已清理、未清理、已关闭)

    +-----------+-------------+--------+------------+
    |ApplicantID|ApplicantName| Status |  HireDate  |
    +-----------+-------------+--------+------------+
    |     1     | John Smith  |Cleaned |08/26/2015  |
    |     2     | Alex Murphy |Closed  |09/12/2015  |
    |     3     | Oliver David|Cleaned |01/11/2015  |
    |     4     | Max Payne   |Unclean |03/18/2015  |
    +-----------+-------------+--------+------------+

我期望的输出,它也应该按年份排序。 例如,我使用变量 @Year 调用 2015 年的所有这些记录。

注意:Total 列是 CleanedUnclean 的总和

   +---------+-----------+-----------+----------+---------+
   |  Month  |  Cleaned  |  Unclean  |  Closed  |  Total  |
   +---------+-----------+-----------+----------+---------+
   |  January|     1     |     0     |    0     |    1    |
   | February|     0     |     0     |    0     |    0    |
   |  March  |     0     |     1     |    0     |    1    |
   |  April  |     0     |     0     |    0     |    0    |
   |  May    |     0     |     0     |    0     |    0    |
   |  June   |     0     |     0     |    0     |    0    |
   |  July   |     0     |     0     |    0     |    0    |
   |  August |     1     |     0     |    0     |    1    |
   |September|     0     |     0     |    1     |    0    |
   |  October|     0     |     0     |    0     |    0    |
   | November|     0     |     0     |    0     |    0    |
   | December|     0     |     0     |    0     |    0    |
   +---------+-----------+-----------+----------+---------+

我似乎无法获得正确的代码,对于 sql,这是我当前的代码。

SELECT Month(HireDate) AS Month, COUNT(*) 
FROM Hires 
GROUP BY Month(HireDate)

我知道我的编码是错误的,因为它不完整。

最佳答案

首先生成一个从 112 的数字列表,以保存所有月份。然后对 Hires 执行 LEFT JOIN 以确保所有缺失的月份都得到考虑。然后对总计使用条件聚合:

SQL Fiddle

;WITH CteMonths AS(
    SELECT * FROM(VALUES
        (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)
    )t(N)
)
SELECT
    Month   = DATENAME(MONTH, DATEADD(MONTH, N-1,0)),
    Cleaned = SUM(CASE WHEN h.Status = 'Cleaned' THEN 1 ELSE 0 END),
    Closed  = SUM(CASE WHEN h.Status = 'Closed' THEN 1 ELSE 0 END),
    Unclean = SUM(CASE WHEN h.Status = 'Unclean' THEN 1 ELSE 0 END),
    Total   = SUM(CASE WHEN h.Status IN('Cleaned', 'Unclean') THEN 1 ELSE 0 END)
FROM CteMonths m
LEFT JOIN Hires h
    ON m.N = MONTH(h.HireDate)
    --AND YEAR(h.HireDate) = @year --uncomment this line to filter for year.
GROUP BY m.N
ORDER BY m.N
<小时/>

如果您想包含年份:

SQL Fiddle

;WITH CteMonths AS(
    SELECT * FROM(VALUES
        (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)
    )t(N)
),
CteYears(yr) AS(
    SELECT DISTINCT YEAR(HireDate) FROM Hires
),
CteAllDates(dt) AS(
    SELECT
        DATEADD(MONTH, m.N - 1, DATEADD(YEAR, y.yr - 1900, 0))
    FROM CteMonths m
    CROSS JOIN CteYears y
)
SELECT
    Year    = YEAR(d.dt),
    Month   = DATENAME(MONTH, d.dt),
    Cleaned = SUM(CASE WHEN h.Status = 'Cleaned' THEN 1 ELSE 0 END),
    Closed  = SUM(CASE WHEN h.Status = 'Closed' THEN 1 ELSE 0 END),
    Unclean = SUM(CASE WHEN h.Status = 'Unclean' THEN 1 ELSE 0 END),
    Total   = SUM(CASE WHEN h.Status IN('Cleaned', 'Unclean') THEN 1 ELSE 0 END)
FROM CteAllDates d
LEFT JOIN Hires h
    ON MONTH(d.dt) = MONTH(h.HireDate)
    AND YEAR(d.dt) = YEAR(h.HireDate)   
GROUP BY YEAR(d.dt), MONTH(d.dt), DATENAME(MONTH, d.dt)
ORDER BY YEAR(d.dt), MONTH(d.dt)

如果您想过滤年份,例如@year = 2015,您可以将之前的 ctes 替换为:

;WITH CteMonths AS(
    SELECT * FROM(VALUES
        (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)
    )t(N)
),
CteAllDates(dt) AS(
    SELECT
        DATEADD(MONTH, m.N - 1, DATEADD(YEAR, @year - 1900, 0))
    FROM CteMonths m
)...

关于sql-server - 将一张表中的 SQL 列分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32218989/

相关文章:

sql-server - Backup-SQLDatabase cmdlet 中的超时问题

sql-server - 具有文化参数的 SQL Server FORMAT 不起作用

java - 为什么 hibernate 在最后添加到我的查询交叉连接

sql - SQL 中的最后一行

.net - 来自带有事务的 dotnet 的 SQL 脚本

sql-server - 在 SQL Server 中,我应该为表或存储过程创建同义词吗?

sql-server - 调整 SQL Server 的 Docker 容器大小

c# - 使用 SQL Server/C# 进行字母数字排序

javascript - 一次等待一个查询

c# - 根据自定义周末计算周数