SQL:复杂查询的问题

SQL:复杂查询的问题,sql,select,mysql,Sql,Select,Mysql,或者至少对我来说这很复杂,因为我完全不懂SQL 我想为我的MySQL-ODBC电话簿程序编写一个查询,它返回一个人的某些详细信息和他的主要电话号码(如果有的话) 人员和数字存储在不同的表(人员和数字)中,而他们的关系存储在npr(数字-人员关系)表中。 “persons”的主键是“nick”,对于“number”是“number”,对于“npr”,是“persons\u nick”和“numbers\u number”。 如果一个数字是主数字,它由npr表的type属性中的某个地方的单词“pri

或者至少对我来说这很复杂,因为我完全不懂SQL

我想为我的MySQL-ODBC电话簿程序编写一个查询,它返回一个人的某些详细信息和他的主要电话号码(如果有的话)

人员和数字存储在不同的表(人员和数字)中,而他们的关系存储在npr(数字-人员关系)表中。
“persons”的主键是“nick”,对于“number”是“number”,对于“npr”,是“persons\u nick”和“numbers\u 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;
当然,如果此人没有主电话号码,则不会返回任何信息。在这种情况下,我如何重写此查询以返回此人的属性和一个空编号


谢谢。

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

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

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

连接的“方向”(或什么)现在可能也错了,我已经玩过了,在我意识到这不是问题之前。是的,两个连接都应该是左的。不幸的是,这不好,因为npr.type可以是任何类型,不仅仅是null或%primary%。有些人可能有很多数字,但没有主数字,在这种情况下,只有当他/她没有数字,或者他/她有主数字时,查询才返回那个人。我不明白,你到底想做什么?你想要它归还什么?如果一个人有一个主要的,那么主要的,否则只是一些随机数?如果一个人有一个主要的,那么主要的,否则为空。(当然,这两种情况下的人的其他属性)所以,像('person1','person','one',''),他有一个基本数字,123456;(‘person2’、‘Dr’、‘person’、‘two’、‘p2.jpg’),他有很多数字,但没有一个标记为primary;他没有数字。好的查询返回的行:('person1','person','one','123456');('person2','Dr','person','two','p2.jpg',NULL);(‘person3’、‘person’、‘three’、‘NULL)。现在,这不会返回person2的行。当没有主键时返回的数字不必为空,它可以是空字符串或类似“0”的常量,我可以在我的程序中将其检测为空电话号码。我应该将它们放在哪里?我试着把我能想到的每一个地方都合并起来,但没有成功:(