【发布时间】:2016-02-18 17:33:20
【问题描述】:
我目前正在尝试改进 SQL Server 上的 SQL 查询。
我的工作台是这样的:
CAT_HISTORY
DATE ID CATEGORY
----------- ----------- -----------
20121201 A 1
20121201 A 1
20121201 B 1
20121201 C 2
20131201 A 2
20131201 B 4
20131201 C 3
20141201 A 3
20141201 B 2
20141201 B 2
20141201 C 1
我的目标是检索他们类别的历史记录。 到目前为止,我正在这样做:
SELECT A.DATE
,COUNT(DISTINCT A.ID) AS NB_CLIENTS
,A.CATEGORY AS STARTING_CAT
,B.CATOGORY AS ENDING_CAT
FROM CAT_HISTORY A
INNER JOIN CAT_HISTORY B
ON (
A.ID= B.ID
AND
(
(
A.DATE = 20121201
AND B.DATE = 20131201
)
OR
(
A.DATE = 20131201
AND B.DATE = 20141201
)
WHERE A.DATE>= 20121201 AND B.DATE<= 20141201
GROUP BY A.DATE, A.CATEGORY,B.CATEGORY
ORDER BY A.DATE, A.CATEGORY,B.CATEGORY
结果是:
DATE_KEY STARTING_CAT ENDING_CAT NB_CLIENTS
----------- ----------- ----------- -----------
20121201 1 2 1
20121201 1 4 1
20121201 2 3 1
20131201 2 3 1
20131201 4 2 1
20131201 2 3 1
但问题是我有更多的日期,我为每个日期添加一个 OR(大约 15 个不同的日期),而且我有很多用户。这意味着查询有时需要长达 15 分钟才能获得结果。
我认为我对 INNER JOIN 的处理过于粗暴,并且可能有一种更优雅、更有效的方法来获得预期的结果。
我的最终目标是让 Sankey 看到随着时间的推移从一个类别到另一个类别的演变,我需要从一个类别转移到另一个类别的用户数量。
使用 Gordon Linoff 的回答,效果很好,但会重复计数
SELECT DISTINCT DATE, CATEGORY,NEXT_CATEGORY, COUNT(*) AS NB_CLIENTS
FROM (
SELECT DISTINCT CH.*, LEAD(CATEGORY) OVER (PARTITION BY CH.ID ORDER BY DATE) AS NEXT_CATEGORY
FROM CAT_HISTORY CH
) CH
WHERE NEXT_CATEGORY IS NOT NULL
GROUP BY DATE, CATEGORY,NEXT_CATEGORY
示例: 预计
DATE_KEY STARTING_CAT ENDING_CAT NB_CLIENTS
----------- ----------- ----------- -----------
20121201 1 2 1
20121201 1 4 1
20121201 2 3 1
20131201 2 3 1
20131201 4 2 1
20131201 2 3 1
使用您的解决方案:
DATE_KEY STARTING_CAT ENDING_CAT NB_CLIENTS
----------- ----------- ----------- -----------
20121201 1 1 1
20121201 1 2 1
20121201 1 4 1
20121201 2 3 1
20131201 2 3 1
20131201 4 2 1
20131201 2 3 1
20141201 2 2 1
最后编辑:
我设法找到了解决方法:
SELECT DISTINCT DATE, CATEGORY,NEXT_CATEGORY, COUNT(*) AS NB_CLIENTS
FROM (
SELECT DISTINCT CH.*, LEAD(CATEGORY) OVER (PARTITION BY CH.ID ORDER BY DATE) AS NEXT_CATEGORY
FROM (SELECT DISTINCT * FROM CAT_HISTORY) CH
) CH
WHERE NEXT_CATEGORY IS NOT NULL
GROUP BY DATE, CATEGORY,NEXT_CATEGORY
【问题讨论】:
-
我更新了我的答案,你有问题,因为我没有添加带有结构的示例数据。关于您的输出结果,我不明白的一件事是,NB_clients 如何根据您的输入数据获得 5 ,1,1,13 个数据,只需解释一下。所以给出更好的答案。
-
谢谢你,我成功了。我已经用相应的数据更新了我的答案。
标签: sql sql-server sql-server-2012 query-optimization