【问题标题】:Error with group by in inner query of correlated sub query相关子查询的内部查询中的 group by 错误
【发布时间】:2017-12-30 08:13:10
【问题描述】:

我编写了以下查询,该查询返回的输出没有任何错误消息,但是我发现输出存在问题:

select productid, productname, categoryid, unitprice
FROM production.products as PP
where unitprice in (select min(unitprice) as minprice 
                    from production.products as PC
                    group by categoryid)
order  by categoryid
go

结果:

24  Product QOGNU   1   4.50
3   Product IMEHJ   2   10.00
19  Product XKXDO   3   9.20
21  Product VJZZH   3   10.00
33  Product ASTMN   4   2.50
52  Product QSRXF   5   7.00
54  Product QAQRL   6   7.45
74  Product BKAZJ   7   10.00
13  Product POXFU   8   6.00

输出显示 categoryid = 3 的多行。当我们按 categoryid 分组时,不应该每个 categoryid 只显示一行(最小单价)吗?

我哪里出错了? 提前感谢大家的帮助。

【问题讨论】:

  • 您只在子查询中进行分组。此外,您的IN 与每个价格进行比较,而不是产品类别中的价格。检查蒂姆的答案,看看如何使用JOIN

标签: sql sql-server sql-server-2012 group-by correlated-subquery


【解决方案1】:

您的查询不相关。你似乎打算:

select productid, productname, categoryid, unitprice
FROM production.products  p
where p.unitprice = (select min(p2.unitprice) as minprice 
                     from production.products p2
                     where p2.categoryid = p.categoryid
                    )
order by p.categoryid;

group by 不是相关子查询。需要where(好吧,有时也需要on)。

您的具体查询存在逻辑问题。它获取价格是任何类别最低价格的任何产品——甚至不是它自己的。

我会这样写:

select p.productid, p.productname, p.categoryid, p.unitprice
from (select p.*,
             min(p.price) over (partition by p.categoryid) as minprice
      from production.products p
     ) p
where p.price = p.minprice
order by p.categoryid;

注意:如果多个产品都具有相同的最低价格,则返回所有产品。如果您特别想要一个,请使用row_number()

select p.productid, p.productname, p.categoryid, p.unitprice
from (select p.*,
             row_number() over (partition by p.categoryid order by p.price asc) as seqnum
      from production.products p
     ) p
where seqnum = 1
order by p.categoryid;

【讨论】:

    【解决方案2】:

    您当前查询的问题在于,最低价格的子查询实际上是所有最低价格的集合,取自每个类别。但是您确实希望将查询限制为每个类别的最低价格。一种方法是加入您的子查询,以您想要的方式限制结果集。

    SELECT
        PP.productid,
        PP.productname,
        PP.categoryid,
        PP.unitprice
    FROM production.products AS PP
    INNER JOIN
    (
        SELECT categoryid, MIN(unitprice) AS minprice 
        FROM production.products
        GROUP BY categoryid
    ) t
        ON PP.categoryid = t.categoryid AND
           PP.unitprice  = t.minprice
    ORDER BY categoryid
    

    【讨论】:

    • 谢谢大家。现在我知道我哪里出错了。您的回答很有帮助!
    【解决方案3】:

    您想获取每个类别的最低单价吗?

     SELECT * FROM (
         SELECT productid, productname, categoryid, unitprice,ROW_NUMBER()OVER(PARTITION BY categoryid ORDER BY unitprice) AS ln
         FROM production.products as PP
     ) AS t WHERE t.ln=1
    order  by categoryid
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多