Sql server 如何为SQL表中的每个项按属性排序找到2个最低值
我有以下三个表格: 产品:产品标识、产品描述 卖方:卖方id、卖方名称 关联:卖家id、产品id、价格 许多卖家出售许多产品。我需要找到两个最便宜的价格为每一个产品订购的增加价格和相应的供应商。理想的列输出为:Sql server 如何为SQL表中的每个项按属性排序找到2个最低值,sql-server,group-by,sql-order-by,Sql Server,Group By,Sql Order By,我有以下三个表格: 产品:产品标识、产品描述 卖方:卖方id、卖方名称 关联:卖家id、产品id、价格 许多卖家出售许多产品。我需要找到两个最便宜的价格为每一个产品订购的增加价格和相应的供应商。理想的列输出为: product_id, product_description, seller_id, seller_name, price p01, milk, s04, walmart, 1.50 p01, milk, s02, target, 2.25 p02, rice, s05, saf
product_id, product_description, seller_id, seller_name, price
p01, milk, s04, walmart, 1.50
p01, milk, s02, target, 2.25
p02, rice, s05, safeway, 1.30
p02, rice, s03, dillons, 1.75
以下是我在SQL server上尝试的内容;这是通向答案的中间一步。我触发了一个错误,但不明白为什么:
SELECT TOP 2 *
FROM
(SELECT A.seller_id, A.product_id, min(price) AS A.price
FROM Association A
GROUP BY A.seller_ID, A.product_id)
ORDER BY A.price ASC
错误是:
Msg 102, Level 15, State 1, Line 8
Incorrect syntax near '.'.
编辑:我使用了本杰明提出的解决方案;这几乎是正确的。以下是查询输出:
卖家id,产品id,价格,m
1 1 7.89 1
3 1 8.00 1
6 1 8.50 1
1 2 12.05 1
6 2 12.50 1
1 3 13.67 1
6 3 15.00 1
1 4 7.66 1
3 4 7.50 1
6 4 8.24 1
值得注意的是,一些产品id值,例如1和4,出现了3次,我只需要两个最低的价格,而不需要第三个或更高的价格。所以我相信这段代码是按价格订购的,但不会删除价格高于第二低的条目 使用CTE更容易:
with min1 as (
SELECT A.seller_id, A.product_id, A.price,
row_number() over (partition by A.seller_id, A.product_id order by a.price asc) as rn
FROM Association A
)
select * from min1
where rn <3
order by seller_id, product_id, price;
为了回答您的问题,您的查询中有一个派生表,有些人可能会将其称为子查询。它必须有别名,所以给它一个 在用于形成派生表的查询中,您使用了不正确的语法。您不应该试图给聚合列指定a.price的名称,并且您应该与您的名称及其拼写保持一致-总有一天,这种不一致会影响您。为什么?首先,这是你错误的根源。如果希望将该列命名为a.price,则需要对其进行分隔,因为它违反了常规标识符的规则。但是不要-句点或圆点有特定的含义/用法,在列名中使用它是非常非常误导的。所以只需给它一个没有句号的别名
... (select A.seller_id, A.product_id, min(A.price) as minprice
from ... ) as MinAssoc
正如您在这段代码中看到的,我给了派生表别名MinAssoc——这是我提到的第一件事。如果不使用此选项,如果只是修复列别名问题,则会遇到错误
接下来,停止使用单字母别名。那就是懒惰。当然,这是一个简短的示例,很容易看到您的代码现在做了什么。但是,你正在建立和强化一些习惯,这些习惯对你没有什么好处。当别人看到这些习惯,需要破译更复杂的查询时,你的工作就会受到不良影响,因为一个字母对理解一行所代表的事物没有任何帮助
这些将修复您的错误,但您需要使用不同的方法实现您的目标-正如已经建议的那样 您可以使用SUB-QUERY或CTE对其进行归档,下面是SUB-QUERY示例:
由于A.price而产生的误差,在你的例子中应该是A.price
SELECT *
FROM
(SELECT A.seller_id,
A.product_id,
price,
ROW_NUMBER() OVER (PARTITION BY A.seller_id, A.product_id order by a.price) as RN
FROM Association A
) as T
Where T.RN <=2
ORDER BY price ASC
单字母别名非常常见,被许多TSQL专家广泛使用。我希望看到您作为子查询解决完整的问题。在CTE之前,我们必须使用子查询,但由于CTE的我的解决方案更常见。我认为这几乎就是我需要它执行的。查询输出了一个我没有预料到的列m。此外,我认为它可以准确地按价格排序,但不会删除第二个最低价格之后的行,即显示产品的第三个最低价格_id=1,4