我有三个表:categories
(id,name),products
(id,category_id,name))和purchases
(id,user_id,product_id)。 product
属于category
。用户可以购买许多products
。我的目的是找到每个用户最受欢迎的category
。
但是,我需要将查询的结果集用作子查询,因此由于SQL Server限制(可怕的ORDER BY
错误),遗憾的是使用任何The ORDER BY clause is invalid in views, inline functions, derived tables, and subqueries, unless TOP is also specified.
语句都是关闭的。
我的方法是为每个用户purchases
创建一个所有category
的列表。然后我有一个MAX
函数来挑选purchases
的最大数量。我将结果连接到原始查询(作为子查询复制)以检索有问题的category_id
,最后我获取类别名称。
我的查询有两个问题:
products
,每个2 categories
就有2个),我最终会为该用户提供一个重复的行。 小提琴:
http://sqlfiddle.com/#!6/8821b/5
如果有人能够帮助我找到确保每个用户只返回一行的方法,以及删除重复的子查询的方法,我将不胜感激。
谢谢!
答案 0 :(得分:5)
首先,感谢您在SQLFiddle中提供示例。它使ALOT变得更容易。
您可以使用row_number更精确地获取" top"记录。在这个例子中,我选择在计数后使用category_name作为辅助排序标准。
SELECT user_id, category_name, category_count
FROM
(
SELECT
user_id, COUNT(1) as category_count, category_name,
ROW_NUMBER() OVER (
PARTITION BY user_id
ORDER BY COUNT(1) DESC, category_name ASC)
as ordinal_position
FROM
purchases p
JOIN products p2 ON p.product_id = p2.id
JOIN categories c ON p2.category_id = c.id
GROUP BY user_id, category_name
) a
WHERE ordinal_position = 1
ORDER BY category_count DESC