或者至少它对我来说很复杂,因为我对SQL完全是个新手。
我想为我的MySQL-ODBC电话簿程序编写一个查询,它返回一个人的某些详细信息和他的主要电话号码(如果有)。
person和number存储在不同的表(person和numbers)中,而它们的关系存储在npr (number-person relations)表中。
'persons‘的主键是'nick','numbers’的主键是'number','npr‘的主键是'persons_nick’和'numbers_number‘。
如果一个数字是主要的,它是由npr表的type属性中的单词" primary“表示的。(我知道它很原始,但我认为我不需要这个属性,现在我没有时间正确地实现它)
下面是现在的代码:
SELECT persons.nick AS nick, persons.fullname AS fullname,
persons.prefix AS prefix, persons.surname AS surname,
persons.forename AS forename, persons.photo AS photo,
numbers.prettynumber AS primarynumber
FROM persons
RIGHT JOIN npr ON npr.persons_nick=persons.nick
LEFT JOIN numbers ON npr.numbers_number=numbers.number
WHERE npr.type LIKE '%primary%'
ORDER BY nick;当然,如果此人没有主电话号码,则不会返回任何内容。在这种情况下,我如何重写此查询以返回人员的属性和无效数字?
谢谢。
发布于 2010-12-12 06:14:51
您的问题的解决方案是将LIKE约束移动到左连接的谓词中:
SELECT persons.nick AS nick, persons.fullname AS fullname,
persons.prefix AS prefix, persons.surname AS surname,
persons.forename AS forename, persons.photo AS photo,
numbers.prettynumber AS primarynumber
FROM persons
RIGHT JOIN npr ON npr.persons_nick=persons.nick
LEFT JOIN numbers ON npr.numbers_number=numbers.number
and
npr.type LIKE '%primary%'
ORDER BY nick;WHERE谓词过滤所有记录,但是连接谓词只属于这个左连接。如果右侧不匹配,则仍然获得连接的左侧。
更新在我看来,在这种情况下只使用左连接会更好。我不知道确切的表定义,但我假设表npr仅用于persons和numbers之间的标记关联。所以如果你只使用左连接,那么你可以确定,你得到了所有的人,无论他们是否有一个主要的号码。
发布于 2010-12-12 05:19:14
在这种情况下,您可以使用IsNull或Coalesce。
发布于 2010-12-12 05:21:13
这是由where子句引起的,因为没有匹配的类型,它将被过滤掉。你可能可以通过这样做来修复它。
WHERE npr.type is null or npr.type LIKE '%primary%' 或者,如果表中的npr.type也可以为null,您可以这样做
WHERE npr.persons_nick is null or npr.type LIKE '%primary%' 因为它不会有npr,所以链接值应该是null,也要在NPR上做一个左连接(不确定这是否重要,我自己从来不使用右连接)
https://stackoverflow.com/questions/4418948
复制相似问题