繁体   English   中英

如何判断 GROUP BY 在 MySQL 的 SELECT 语句中选择了哪一行?

[英]How to tell which row is chosen by GROUP BY in a SELECT statement in MySQL?

我有一张名为products的表:

╔═══════════╦══════════╦════════════╗
║ productID ║ designID ║ isFeatured ║
╠═══════════╬══════════╬════════════╣
║ 111111111 ║ AAAAA    ║ 0          ║
║ 222222222 ║ AAAAA    ║ 1          ║
║ 333333333 ║ AAAAA    ║ 0          ║
║ 444444444 ║ BBBBB    ║ 0          ║
║ 555555555 ║ BBBBB    ║ 0          ║
║ 666666666 ║ CCCCC    ║ 0          ║
║ 777777777 ║ DDDDD    ║ 0          ║
║ 888888888 ║ DDDDD    ║ 0          ║
║ 999999999 ║ DDDDD    ║ 1          ║
╚═══════════╩══════════╩════════════╝

isFeatured (BOOL) 可以具有值10 (并且每个designID行只有一个isFeatured可能是1 ,所有其他的都是0 。或者每个designID也可能所有isFeatured都是0 。)

现在我想从表中过滤我的结果,使每个designID只显示一行,但如果它有isFeatured = 1 ,则应该选择这一行。 在其他情况下,它根本不重要。 像这样:

╔═══════════╦══════════╦════════════╗
║ productID ║ designID ║ isFeatured ║
╠═══════════╬══════════╬════════════╣
║ 222222222 ║ AAAAA    ║ 1          ║
║ 444444444 ║ BBBBB    ║ 0          ║
║ 666666666 ║ CCCCC    ║ 0          ║
║ 999999999 ║ DDDDD    ║ 1          ║
╚═══════════╩══════════╩════════════╝

但无论我尝试什么,我总是使用GROUP BY得到相同的结果。

首先,我通过以下语句进行了尝试:

   SELECT designID, productID, isFeatured
     FROM products 
 GROUP BY designID 
 ORDER BY isFeatured DESC, designID ASC 

我得到了某事。 像这样:

╔═══════════╦══════════╦════════════╗
║ productID ║ designID ║ isFeatured ║
╠═══════════╬══════════╬════════════╣
║ 111111111 ║ AAAAA    ║ 0          ║
║ 444444444 ║ BBBBB    ║ 0          ║
║ 666666666 ║ CCCCC    ║ 0          ║
║ 777777777 ║ DDDDD    ║ 0          ║
╚═══════════╩══════════╩════════════╝

这不起作用,因为排序发生在分组之后。 好的,到此我就明白了。

搜索了一段时间后,我想出了这个尝试:

SELECT designID, productID, isFeatured
  FROM ( 
      SELECT * 
        FROM products 
    ORDER BY isFeatured DESC 
) sub 
GROUP BY designID 
ORDER BY isFeatured DESC, designID ASC

这给了我以前的确切结果。 但我不明白为什么,因为它正在对另一组行进行分组(具有不同的顺序)?

所以我的问题是:

  1. 为什么我的第二个陈述不起作用?
  2. 获得预期结果的正确说法是什么?

谢谢!

这是一种可能

CREATE TABLE products ( `productID` INTEGER, `designID` VARCHAR(5), `isFeatured` INTEGER ); INSERT INTO products (`productID`, `designID`, `isFeatured`) VALUES ('111111111', 'AAAAA', '0'), ('222222222', 'AAAAA', '1'), ('333333333', 'AAAAA', '0'), ('444444444', 'BBBBB', '0'), ('555555555', 'BBBBB', '0'), ('666666666', 'CCCCC', '0'), ('777777777', 'DDDDD', '0'), ('888888888', 'DDDDD', '0'), ('999999999', 'DDDDD', '1');
 SELECT productID,designID,isFeatured FROM products WHERE isFeatured = 1 UNION SELECT MIN(productID),designID,isFeatured FROM products WHERE designID NOT IN (SELECT designID FROM products WHERE isFeatured = 1) GROUP BY designID,isFeatured
 产品ID | 设计ID |  isFeatured --------: |:-------- |  ---------: 222222222 |  AAAAA |  1 999999999 |  DDDD |  1 444444444 |  BBBBB |  0 666666666 | 中交 |  0
 SELECT DISTINCT FiRST_VALUE(productID) OVER ( PARTITION BY designID ORDER BY isFeatured DESC ) productID, `designID`,FiRST_VALUE(isFeatured) OVER ( PARTITION BY designID ORDER BY isFeatured DESC ) isFeatured FROM products
 产品ID | 设计ID |  isFeatured --------: |:-------- |  ---------: 222222222 |  AAAAA |  1 444444444 |  BBBBB |  0 666666666 | 中交 |  0 999999999 |  DDDD |  1

db<> 在这里摆弄

  1. 您的第二个陈述在MySQL 5.55.6下给出了正确答案。 但是,它在MySQL 5.78.0下给出了错误的答案。 事实上, MySQL 5.78.0阻止了具有不依赖功能的列的GROUP BY ,我们需要在sql_mode ONLY_FULL_GROUP_BY强制运行该语句。 我猜想MySQL 5.78.0GROUP BY的底层代码在这里没有涵盖这个问题。

  2. 通过简单地将子查询移出到另一个表,可以在MySQL 5.78.0中修复结果。

CREATE TABLE sub AS SELECT * 
    FROM products 
    ORDER BY isFeatured DESC;

SELECT productID, designID, isFeatured
--  FROM ( 
--      SELECT * 
--        FROM products 
--    ORDER BY isFeatured DESC 
-- ) sub
FROM sub 
GROUP BY designID 
ORDER BY isFeatured DESC, designID ASC;
productID   designID  isFeatured
======================
222222222   AAAAA   1
999999999   DDDDD   1
444444444   BBBBB   0
666666666   CCCCC   0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM