SELECT *
FROM `eBayorders`
WHERE (`OrderIDAmazon` IS NULL
OR `OrderIDAmazon` = "null")
AND `Flag` = "True"
AND `TYPE` = "GROUP"
AND (`Carrier` IS NULL
OR `Carrier` = "null")
AND LEFT(`SKU`, 1) = "B"
AND datediff(now(), `TIME`) < 4
AND (`TrackingInfo` IS NULL
OR `TrackingInfo` = "null")
AND `STATUS` = "PROCESSING"
GROUP BY `Name`,
`SKU`
ORDER BY `TIME` ASC LIMIT 7
我正在努力确保所有名称和skus都不会出现在同一个结果中。我试图按名称分组,然后sku,但是我遇到了一个问题,结果显示有相同的名称和不同的skus,我不想发生。如何修复此查询以确保结果集中始终存在不同的名称和skus?!
例如说我有订单:
Name: Ben Z, SKU : B000334, oldest
Name: Ben Z, SKU : B000333, second oldest
Name: Will, SKU: B000334, third oldest
Name: John, SKU: B000036, fourth oldest
The query should return only:
Name: Ben Z, SKU : B000334, oldest
Name: John, SKU: B000036, fourth oldest
这是因为所有名称在SKU中只有一个条目。
答案 0 :(得分:2)
这里有两个问题。
第一个是ANSI标准,如果你有一个CSS.Property.BORDER_BOTTOM_COLOR
子句,你可以放在GROUP BY
子句中的唯一内容是SELECT
中列出的项目或使用聚合函数(SUM,COUNT,MAX等)。您问题中的查询会选择表格中的所有列,即使是GROUP BY
中没有的列。如果您有多个与组匹配的记录,则该表不知道要为这些额外列使用哪条记录。
MySql对此很愚蠢。理智的数据库服务器会抛出错误并拒绝运行该查询。 Sql Server,Oracle和Postgresql都会这样做。 MySql会猜测你想要的数据。让数据库服务器猜测数据通常不是一个好主意。
但这并没有解释重复的问题......为什么坏查询会运行。您有重复的原因是您在GROUP BY
和Name
上进行了分组。因此,例如,对于SKU
的记录,您只想查看最旧的SKU。但是,当您对Ben Z
和Name
进行分组时,您会得到SKU
和{ Ben Z, B000334 }
的单独组...这是Ben Z的两行,但它是查询的内容要求,因为SKU也是决定一个团体的一部分。
如果您只想查看每人一条记录,则只需按人员字段进行分组。这可能意味着首先构建查询的那一部分,以确定所需的基本记录集,然后作为完整解决方案的一部分加入此原始查询。
答案 1 :(得分:2)
SELECT T1.*
FROM eBayorders T1
JOIN
( SELECT `Name`,
`SKU`,
max(`TIME`) AS MAX_TIME
FROM eBayorders
WHERE (`OrderIDAmazon` IS NULL OR `OrderIDAmazon` = "null") AND `Flag` = "True" AND `TYPE` = "GROUP" AND (`Carrier` IS NULL OR `Carrier` = "null") AND LEFT(`SKU`, 1) = "B" AND datediff(now(), `TIME`) < 4 AND (`TrackingInfo` IS NULL OR `TrackingInfo` = "null") AND `STATUS` = "PROCESSING"
GROUP BY `Name`,
`SKU`) AS dedupe ON T1.`Name` = dedupe.`Name`
AND T1.`SKU` = dedupe.`SKU`
AND T1.`Time` = dedupe.`MAX_TIME`
ORDER BY `TIME` ASC LIMIT 7
您的数据库平台应该投诉,因为您的原始查询在选择列表中的项目不在组中(通常不允许)。以上应该解决它。
如果你的数据库支持窗口函数(不幸的是,MySQL没有),那么更好的选择是:
SELECT *
FROM
( SELECT *,
row_number() over (partition BY `Name`, `SKU`
ORDER BY `TIME` ASC) AS dedupe_rank
FROM eBayorders
WHERE (`OrderIDAmazon` IS NULL OR `OrderIDAmazon` = "null") AND `Flag` = "True" AND `TYPE` = "GROUP" AND (`Carrier` IS NULL OR `Carrier` = "null") AND LEFT(`SKU`, 1) = "B" AND datediff(now(), `TIME`) < 4 AND (`TrackingInfo` IS NULL OR `TrackingInfo` = "null") AND `STATUS` = "PROCESSING" ) T
WHERE dedupe_rank = 1
ORDER BY T.`TIME` ASC LIMIT 7
答案 2 :(得分:1)
您正在尝试获取SKU和Name列中没有重复的结果集。
您可能需要在查询中添加subquery
才能完成此操作。内部查询将按名称分组,外部查询将按SKU分组,这样您就不会在任一列中重复。
试试这个:
SELECT *
FROM
(SELECT *
FROM eBayorders
WHERE (`OrderIDAmazon` IS NULL
OR `OrderIDAmazon` = "null")
AND `Flag` = "True"
AND `TYPE` = "GROUP"
AND (`Carrier` IS NULL
OR `Carrier` = "null")
AND LEFT(`SKU`, 1) = "B"
AND datediff(now(), `TIME`) < 4
AND (`TrackingInfo` IS NULL
OR `TrackingInfo` = "null")
AND `STATUS` = "PROCESSING"
GROUP BY Name)
GROUP BY `SKU`
ORDER BY `TIME` ASC LIMIT 7
答案 3 :(得分:0)
使用这种方法,您只需过滤掉不包含TIME的最大/最新值的行。
SELECT SKU, Name
FROM eBayOrders o
WHERE NOT EXISTS (SELECT 0 FROM eBayOrders WHERE Name = o.name and Time > o.Time)
GROUP BY SKU, Name
注意:如果两个记录具有完全相同的名称和时间值,您可能仍然会得到重复项,因为您指定的逻辑没有提供任何方法来打破平局。