如何按月和年分组并分开条目?

时间:2016-11-16 15:17:39

标签: sql sql-server grouping counting

我有一个包含以下数据的表[MY_TABLE]:日期[DOCUMENT_DATE]和状态[STATUS]。我想分离和统计3个不同的状态:当状态<时打开8,当状态= 8时丢失或者当状态>时获胜8按年和月分组。

最终结果将是这样的:year, month, count(won), count(lost), count(open),有效地给出每个月每个状态的计数。

有些月份根本没有状态(可以忽略),有些只有一些状态而不是所有状态(应该正确写月份和年份)

我现在有一个有效的查询,但它真的很大:

SELECT
CASE WHEN "open".year IS NOT NULL
    THEN
      "open".year
  ELSE
    (CASE WHEN "lost".year IS NOT NULL
      THEN
        "lost".year
     ELSE
       "won".year
     END)
  END          AS "Année",
  CASE WHEN "open".month IS NOT NULL
    THEN
      "open".month
  ELSE
    (CASE WHEN "lost".month IS NOT NULL
      THEN
        "lost".month
     ELSE
       "won".month
     END)
  END          AS "Mois",
  "open".count AS "Ouvertes",
  "lost".count AS "Perdues",
  "won".count  AS "Gagnées"
FROM (SELECT
        year([DOCUMENT_DATE])  AS "year",
        MONTH([DOCUMENT_DATE]) AS "month",
        COUNT(*)               AS "count"
      FROM [MY_TABLE]
      WHERE [STATUS] < 8 AND [DOCUMENT_DATE] >= ?1 AND [DOCUMENT_DATE] <= ?2 AND ([SEGMENT] = ?3 OR ?3 IS NULL)
      GROUP BY YEAR([DOCUMENT_DATE]), MONTH([DOCUMENT_DATE])) AS "open"
  FULL JOIN (SELECT
               year([DOCUMENT_DATE])  AS "year",
               MONTH([DOCUMENT_DATE]) AS "month",
               COUNT(*)               AS "count"
             FROM [MY_TABLE]
             WHERE [STATUS] = 8 AND [DOCUMENT_DATE] >= ?1 AND [DOCUMENT_DATE] <= ?2 AND ([SEGMENT] = ?3 OR ?3 IS NULL)
             GROUP BY YEAR([DOCUMENT_DATE]), MONTH([DOCUMENT_DATE])) AS "lost"
    ON "open".month = "lost".month AND "open".year = "lost".year
  FULL JOIN (SELECT
               year([DOCUMENT_DATE])  AS "year",
               MONTH([DOCUMENT_DATE]) AS "month",
               COUNT(*)               AS "count"
             FROM [MY_TABLE]
             WHERE [STATUS] > 8 AND [DOCUMENT_DATE] >= ?1 AND [DOCUMENT_DATE] <= ?2 AND ([SEGMENT] = ?3 OR ?3 IS NULL)
             GROUP BY YEAR([DOCUMENT_DATE]), MONTH([DOCUMENT_DATE])) AS "won"
    ON "open".month = "won".month AND "open".year = "won".year
ORDER BY CASE WHEN "open".year IS NOT NULL
  THEN
    "open".year
         ELSE
           (CASE WHEN "lost".year IS NOT NULL
             THEN
               "lost".year
            ELSE
              "won".year
            END)
         END,
  CASE WHEN "open".month IS NOT NULL
    THEN
      "open".month
  ELSE
    (CASE WHEN "lost".month IS NOT NULL
      THEN
        "lost".month
     ELSE
       "won".month
     END)
END

我很确定有一种更简单,更清洁的方法,但我无法理解。

1 个答案:

答案 0 :(得分:5)

根据描述,我认为这可能是您正在寻找的。

SELECT  year([DOCUMENT_DATE])  AS "year",
        MONTH([DOCUMENT_DATE]) AS "month",
        COUNT(case when [STATUS] > 8 then 1 end) win_count,    
        COUNT(case when [STATUS] = 8 then 1 end) lost_count,
        COUNT(case when [STATUS] < 8 then 1 end) open_count
FROM [MY_TABLE]
GROUP BY year([DOCUMENT_DATE]),MONTH([DOCUMENT_DATE])
ORDER BY 1,2

如果条件在所有计数中都是通用的,则添加WHERE [DOCUMENT_DATE] >= ?1 AND [DOCUMENT_DATE] <= ?2 AND ([SEGMENT] = ?3 OR ?3 IS NULL)