SQL:复杂查询的问题

发布于 2024-10-06 21:08:21 字数 808 浏览 1 评论 0原文

或者至少对我来说这很复杂,因为我对 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

落花浅忆 2024-10-13 21:08:21

问题的解决方案是将 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 仅用于人员和数字之间的标记关联。因此,如果您仅使用左连接,那么您可以确定,您可以获得所有人,无论他们是否有主号码。

The solution for your problem is to move the LIKE constraint into the predicate of the left join:

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;

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.

So要识趣 2024-10-13 21:08:21

在这种情况下,您可以使用 IsNullCoalesce

You can use IsNull or Coalesce in that situation.

错爱 2024-10-13 21:08:21

这是由你的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 上执行左连接(不确定这是否重要,我自己从不使用右连接)

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

WHERE npr.type is null or npr.type LIKE '%primary%' 

or if npr.type can also be null in the table, you could do

WHERE npr.persons_nick is null or npr.type LIKE '%primary%' 

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)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文