SQL:复杂查询的问题
或者至少对我来说这很复杂,因为我对 SQL 完全是菜鸟。
我想为我的 MySQL-ODBC 电话簿程序编写一个查询,该查询返回一个人的某些详细信息及其主要电话号码(如果有的话)。
人物和数字存储在不同的表(人物和数字)中,而他们的关系则在npr(数字-人物关系)表中。
“persons”的主键是“nick”,“numbers”的主键是“number”,“npr”的主键是“persons_nick”和“numbers_number”。
如果某个数字是主要号码,则由 npr 表的类型属性中的“主要”一词表示。 (我知道它很原始,但我认为我不需要这个属性,现在我没有时间正确实现它)
这是现在的代码:
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;
如果此人没有主要电话号码。在这种情况下,我如何重写此查询以返回该人的属性和无效号码?
谢谢。
Or at least it's complex for me, as I'm a total noob with SQL.
I'd like to write a query for my MySQL-ODBC phonebook program, that returns certain details of a person and his primary phone number if there's one.
Persons and numbers are stored in different tables (persons and numbers), while their relations are in the npr (number-person relations) table.
The primary key of 'persons' is 'nick', for 'numbers' it's 'number', for 'npr' it's 'persons_nick' and 'numbers_number' together.
If a number is primary, it's signalled by the word "primary" being somewhere in the type attribute of the npr table. (I know it's primitive, but I didn't think I'd need this attribute and now I don't have time to implement it properly)
Here's the code as it is now:
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;
This, of course doesn't return anything if the person doesn't have a primary phone number. How could I rewrite this query to return the person's attributes and a void number in that case?
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
问题的解决方案是将 LIKE 约束移至左连接的谓词中:
WHERE 谓词过滤所有记录,但连接谓词仅属于此左连接。如果右侧不匹配,那么您仍然会得到连接的左侧。
更新
在我看来,在这种情况下最好只使用左连接。我不知道确切的表定义,但我假设表 npr 仅用于人员和数字之间的标记关联。因此,如果您仅使用左连接,那么您可以确定,您可以获得所有人,无论他们是否有主号码。
The solution for your problem is to move the LIKE constraint into the predicate of the left join:
The WHERE predicate filters all records but the join predicate belongs only to this left join. If the right side doesn't match, then you still get the left side of the join.
Update
It seems to me that it would be better to only use left joins in this case. I don't know the exact table definitions, but I assume that table npr is only for the tagged association between persons and numbers. So if you use only left joins then you can be sure, you get all persons whether or not they have a primary number.
在这种情况下,您可以使用
IsNull
或Coalesce
。You can use
IsNull
orCoalesce
in that situation.这是由你的where子句引起的,因为没有匹配的类型会被过滤掉。您可能可以通过执行类似的操作来修复它
,或者如果 npr.type 在表中也可以为 null,您可以这样做,
因为它没有 npr,链接的值应该为 null,还可以在 NPR 上执行左连接(不确定这是否重要,我自己从不使用右连接)
this is caused by your where clause, because there's no type to match it will be filtered out. You can probably fix it by doing the where something like
or if npr.type can also be null in the table, you could do
since it won't have an npr the linked value should be null, also do a left join on the NPR (not sure if that matters though, I never use right joins myself)