SQL Query似乎返回了一个不完整的结果集

时间:2015-03-23 19:11:33

标签: mysql sql

以下查询返回许多正确的行,但不返回种子的行=' 1985.00-Miller-13' (还有其他人失踪,但这只是一个例子):

SELECT g.dam_alias "Seed" 
FROM genetic g LEFT OUTER JOIN (genetic g1d)
ON (g.dam_alias = g1d.genetic_alias)
GROUP BY g1d.dam_alias , g1d.sire_alias;

但是,如果我在查询中添加WHERE子句,指定我认为缺少的行,则会显示。这是修改过的查询:

SELECT g.dam_alias "Seed"
FROM genetic g LEFT OUTER JOIN (genetic g1d)
ON (g.dam_alias = g1d.genetic_alias)
WHERE g.dam_alias = '1985.00-Miller-13' -- this is the added line
GROUP BY g1d.dam_alias , g1d.sire_alias;

如果我的原始查询确实不应该返回种子" 1985.00-Miller-13"的行,我原本期望第二个查询不返回任何行。

起初我怀疑我的密钥/索引已损坏,因此我进行了数据库转储并从生成的sql脚本重建。我使用MYSQL v5.6和MariasDB v 10.0.17

复制了这个问题

我亲手检查了数据并在纸上查询了查询,发现任何与我的预期结果不一致的内容。

任何建议都将不胜感激。我可以提供任何人可能需要的任何其他信息/架构/数据。

感谢。

2 个答案:

答案 0 :(得分:2)

您正在g1d.dam_alias进行分组,但选择g.dam_alias

大多数其他RDBMS产品不允许从组中选择未聚合的列,因为从记录组中的记录应该返回一个值是不明确的。然而,MySQL确实允许此操作作为性能增强,尽管文档清楚表明这种情况下的结果是不确定的:

MySQL Handling of GROUP BY(重点补充):

  

MySQL扩展了GROUP BY的使用,以便选择列表可以引用未在GROUP BY子句中命名的非聚合列。这意味着前面的查询在MySQL中是合法的。您可以通过避免不必要的列排序和分组来使用此功能来获得更好的性能。但是,当GROUP BY中未在g.dam_alias = '1985.00-Miller-13'中命名的每个非聚合列中的所有值对于每个组都相同时,这非常有用。 服务器可以自由选择每个组中的任何值,因此除非它们相同,否则所选的值是不确定的。

在某些群组中存在g.dam_alias的情况(可能是我们无法确定地看不到基础数据),但会选择与这些群组中的其他记录不同的{{1}}值。添加过滤器时,没有其他值可供选择,因此所选的值保证是您期望的值。

如果不了解所需查询的语义,很难提出修复此问题的建议。

答案 1 :(得分:1)

您正在使用left outer joingroup by引用了第二个表。这些值可以是NULL。从第一个表中获取列:

SELECT g.dam_alias "Seed"
FROM genetic g LEFT OUTER JOIN 
     genetic g1d
     ON g.dam_alias = g1d.genetic_alias
GROUP BY g.dam_alias, g1d.sire_alias;
---------^