我希望你能帮助我解决这个话题。
我有一个表,相关字段是VARCHAR id,VARCHAR名称和日期
3DF0001AB TESTING_1 2017-04-04
3DF0002ZG TESTING_2 2017-04-03
3DF0003ER TESTING_1 2017-04-01
3DF0004XY TESTING_1 2017-03-26
3DF0005UO TESTING_3 2017-03-25
目标是为每个名称(> 500)检索两个条目,按日期排序。因为我可以使用数据库查询,我尝试了以下方法。为每个名称获取一个id,UNION使用相同的查询获得结果,但不包括第一组中的ID。
第一步是为每个名字输入一个条目。按预期结果,每个名称都有一个id。
SELECT id FROM table GROUP BY name;
第二步;使用WHERE子句中的上述语句来接收不在第一个结果中的结果:
SELECT id FROM table WHERE id NOT IN (SELECT id FROM table GROUP BY name)
但是结果是空的,然后我尝试使用WHERE id IN
而不是NOT IN
来反转WHERE。预期的结果是,只使用子查询时会显示相同的id,结果是表中的所有ID。所以我假设子查询提供了错误的结果,因为当我手动复制id时,> id IN ("3DF0001AB", ...)
它有效。
所以也许有人可以解释行为和/或帮助找到原始问题的解决方案。
答案 0 :(得分:1)
这是一个非常糟糕的做法:
SELECT id
FROM table
GROUP BY name;
虽然MySQL允许此构造,但返回的id
来自 indeterminate 行。在不同的时间运行相同的查询时,甚至可以获得不同的行。
更好的方法是使用聚合函数:
SELECT MAX(id)
FROM table
GROUP BY name;
但你真正的问题却略有不同。使用NOT IN
时,如果IN
列表中的任何值为NULL
,则不会返回任何行。这就是定义NOT IN
的方式。
我建议改用NOT EXISTS
或LEFT JOIN
,因为他们的行为更直观:
SELECT t.id
FROM table t LEFT JOIN
(SELECT MAX(id) as id
FROM table t2
GROUP BY name
) tt
ON t.id = tt.id
WHERE tt.id IS NULL;