SQL服务器:如何只对部分语法进行分组
SQL Server : how to group only part of the syntax
我在创建 SQL 服务器查询时遇到问题。
总而言之,查询应该得到 sum 和 count 的列,按 customerID
分组,另一列按未用作 grouper 列的列分组。
我的问题是只对部分语法进行分组,而列不需要分组的情况。
样本数据,测试:
customerID, 1,2,3,4...
InvoiceID, 1234551, 1234552...
ProductID, A, B, C...
Date, Datetime
Income, int
customerID
InvoiceID
ProductID
Date
Income
1
1234551
A
01/01/2015
300
2
1234552
B
02/01/2016
300
我有一个解决方案,但我确信还有一个更简单的解决方案。
SELECT DISTINCT
Test.CustomerId,
ISNULL(TBL.Income_2015, 0) AS Income_2015,
ISNULL(TBL_2.Income_2016, 0) AS Income_2016,
CASE
WHEN Test.ProductID = 'A'
THEN 'TRUE'
ELSE 'FALSE'
END AS 'purchase_product_A',
TBL_3.Invoices
FROM
Test
LEFT OUTER JOIN
(SELECT CustomerId, SUM(Income) AS Income_2015
FROM Test
WHERE YEAR(Date) = 2015
GROUP BY CustomerId) TBL ON Test.customerID = TBL.customerID
LEFT OUTER JOIN
(SELECT CustomerId, SUM(Income) AS Income_2016
FROM Test
WHERE YEAR(Date) = 2016
GROUP BY CustomerId) TBL_2 ON Test.customerID = TBL_2.customerID
LEFT OUTER JOIN
(SELECT CustomerId, COUNT(InvoiceID) AS Invoices
FROM Test
GROUP BY CustomerId) TBL_3 ON Test.customerID = TBL_3.customerID
生产:
customerID, 1,2,3...
Income_2015, int
Income_2016, int
Invoices, int
Purchase_product_A, boolean
customerID
Income_2015
Income_2016
Invoices
Purchase_product_A
1
300
300
2
TRUE
10
0
400
1
FALSE
谢谢!
尼尔
您可以对单次查询使用条件聚合:
SELECT
CustomerId,
SUM(CASE WHEN YEAR(Date) = 2015 THEN Income ELSE 0 END) AS Income_2015,
SUM(CASE WHEN YEAR(Date) = 2016 THEN Income ELSE 0 END) AS Income_2016,
COUNT(InvoiceID) AS Invoices,
CASE WHEN COUNT(CASE WHEN ProductID = 'A' THEN 1 END) > 0
THEN 'TRUE' ELSE 'FALSE' END AS [Purchase_product_A]
FROM Test
GROUP BY
CustomerId;
我在创建 SQL 服务器查询时遇到问题。
总而言之,查询应该得到 sum 和 count 的列,按 customerID
分组,另一列按未用作 grouper 列的列分组。
我的问题是只对部分语法进行分组,而列不需要分组的情况。
样本数据,测试:
customerID, 1,2,3,4...
InvoiceID, 1234551, 1234552...
ProductID, A, B, C...
Date, Datetime
Income, int
customerID | InvoiceID | ProductID | Date | Income |
---|---|---|---|---|
1 | 1234551 | A | 01/01/2015 | 300 |
2 | 1234552 | B | 02/01/2016 | 300 |
我有一个解决方案,但我确信还有一个更简单的解决方案。
SELECT DISTINCT
Test.CustomerId,
ISNULL(TBL.Income_2015, 0) AS Income_2015,
ISNULL(TBL_2.Income_2016, 0) AS Income_2016,
CASE
WHEN Test.ProductID = 'A'
THEN 'TRUE'
ELSE 'FALSE'
END AS 'purchase_product_A',
TBL_3.Invoices
FROM
Test
LEFT OUTER JOIN
(SELECT CustomerId, SUM(Income) AS Income_2015
FROM Test
WHERE YEAR(Date) = 2015
GROUP BY CustomerId) TBL ON Test.customerID = TBL.customerID
LEFT OUTER JOIN
(SELECT CustomerId, SUM(Income) AS Income_2016
FROM Test
WHERE YEAR(Date) = 2016
GROUP BY CustomerId) TBL_2 ON Test.customerID = TBL_2.customerID
LEFT OUTER JOIN
(SELECT CustomerId, COUNT(InvoiceID) AS Invoices
FROM Test
GROUP BY CustomerId) TBL_3 ON Test.customerID = TBL_3.customerID
生产:
customerID, 1,2,3...
Income_2015, int
Income_2016, int
Invoices, int
Purchase_product_A, boolean
customerID | Income_2015 | Income_2016 | Invoices | Purchase_product_A |
---|---|---|---|---|
1 | 300 | 300 | 2 | TRUE |
10 | 0 | 400 | 1 | FALSE |
谢谢! 尼尔
您可以对单次查询使用条件聚合:
SELECT
CustomerId,
SUM(CASE WHEN YEAR(Date) = 2015 THEN Income ELSE 0 END) AS Income_2015,
SUM(CASE WHEN YEAR(Date) = 2016 THEN Income ELSE 0 END) AS Income_2016,
COUNT(InvoiceID) AS Invoices,
CASE WHEN COUNT(CASE WHEN ProductID = 'A' THEN 1 END) > 0
THEN 'TRUE' ELSE 'FALSE' END AS [Purchase_product_A]
FROM Test
GROUP BY
CustomerId;