我有一张购买表:
id_purchase, date (timestamp), city ($), price, ...
15484, 1516004158, Phoenix, 147.56, ...
14879, 1516097654, Chicago, 47.99, ...
14788, 1515931918, New Yokr, 87.45, ...
我需要为购买次数最多的十个城市创建每周比较。
WITH
w1 AS
(SELECT * FROM purchases WHERE relative date limitation),
w2 AS
(SELECT * FROM purchases WHERE relative date limitation),
top_cities
(SELECT city FROM w2
GROUP BY 1
ORDER BY count(*) DESC)
SELECT w2.city,
w1.count(*),
w2.count(*),
(w2.count(*)/w1.count(*))-1)*100.00 AS Ratio
FROM w1, w2
WHERE w1.city IN (SELECT * FROM top_cities)
GROUP BY 1
ORDER BY 4 ASC
但查询速度很慢,因此我因超时限制而收到错误。
我想得到的结果如下:
city, w1, w2, Ratio
Chichago, 245, 274, 11.84
Phoenix, 147, 197, 34.01
...
谢谢!
答案 0 :(得分:0)
这就是我想到的 - 它会将数据输出为行,这些行更容易从应用程序代码中消耗,您可以进一步过滤和处理它。
架构与您问题的所需输出不符,因为您要求排名前10位的城市"但是你的代码只输出数据作为两个明确命名的列,所以它非常不清楚你希望它如何工作。
这是用于MS SQL Server 2000或更高版本的T-SQL编写的。如果用方括号替换方括号[
]
并使用EXTRACT( )
而不是YEAR
和DATEPART
替换大多数其他数据库系统应该能够使用此功能。
SELECT
city,
YEAR( [date] ) AS [year],
DATEPART( wk, [date] ) AS [weekNumber]
COUNT(*) AS [count]
FROM
purchases
INNER JOIN
(
SELECT
TOP 10
city,
COUNT(*) AS [count]
FROM
purchases
GROUP BY
city
ORDER BY
[count] DESC
) AS top10Cities ON purchases.city = top10Cities.city
GROUP BY
city,
YEAR( [date] ),
DATEPART( wk, [date] )
通过从内到外阅读来更好地理解这个查询:从找到前10个城市的最里面的子查询top10Cities
开始,然后它使用这些城市名称来限制返回的行,这些行按周汇总所有购买量 - 数。在我看来,将周数转换为实际日期是一个视图级别的问题,而不是应该在SQL内部完成的事情。