我在数据库中有一些抓取的产品数据,我想在我的网站上使用它们。 我想编写一个查询,返回标题为“%EXAMPLE%”的所有项目,但仅包含唯一的产品。
问题是我有 1 个项目的多行,并且我只想返回每个产品 1 行(我每天都会抓取,因此每天每个项目都会获得额外的行)。行之间的唯一区别是它们有另一个日期和价格,因为这就是我所寻找的价格历史记录。
示例: 我们有 3 种商品:粉红巧克力、粉红苹果和粉红梨。 每个项目有 3 行,因为我刮擦了 3 次。 例如(出于本示例的目的,我没有添加所有其他列):
产品ID | 标题 | 价格 | 可用 |
---|---|---|---|
ABC123DEF | 粉红苹果 | 0.47 | 1 |
ABC123DEF | 粉红苹果 | 0.42 | 1 |
ABC123DEF | 粉红苹果 | 0.41 | 1 |
ABC333FHG | 粉红梨 | 0.41 | 1 |
ABC333FHG | 粉红梨 | 0.41 | 1 |
ABC333FHG | 粉红梨 | 0.41 | 1 |
FH5845FJG | 粉红巧克力 | 0.41 | 1 |
FH5845FJG | 粉红巧克力 | 0.41 | 1 |
FH5845FJG | 粉红巧克力 | 0.41 | 1 |
我想要得到的结果是:
产品ID | 标题 | 价格 | 可用 |
---|---|---|---|
ABC123DEF | 粉红苹果 | 0.47 | 1 |
ABC333FHG | 粉红梨 | 0.41 | 1 |
FH5845FJG | 粉红巧克力 | 0.41 | 1 |
看来我必须搜索标题,然后过滤掉重复的productId,以便得到正确的结果。但我不知道该怎么做。
有什么想法吗?
P粉2983052662024-04-03 00:53:42
一个例子:
WITH cte AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY productId ORDER BY price DESC) rn FROM test ) DELETE test FROM test NATURAL JOIN cte WHERE cte.rn > 1;
查询保存每个产品 ID 的最高价格行,并删除该产品的其他行。
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=40df8e8e4b3eb206e0f73b7ce3a70a a5一个>
注意 - 必须存储的每个完整行都是唯一的(必须删除的行可能具有完整的重复项)。
WITH cte AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY productId ORDER BY price DESC) rn FROM test ) SELECT * FROM cte WHERE rn = 1;
此查询不需要行是唯一的,在这种情况下仅返回一个行副本。如果您需要所有副本,请使用 RANK() 或 DENSE_RANK() 而不是 ROW_NUMBER()。
MySQL 5.x 版本的解决方案。
SELECT * FROM test WHERE NOT EXISTS ( SELECT NULL FROM test t WHERE test.productId = t.productId AND test.price < t.price );
此查询将返回所有副本(如果存在)。如果您只需要一份副本,请添加 DISTINCT。