MySQL从子查询返回数组,并且为NULL

时间:2014-02-27 13:35:29

标签: mysql arrays null subquery

我有两个表,“记录”和“信息”。

“记录”表格如下:

mysql> SELECT * FROM records WHERE num = '7';
+-----+--------+----+------+-----+-----+------------+-----------+----------+---------------------+
| id  | city   | st | type | num | val | startdate  | status    | comments | updated             |
+-----+--------+----+------+-----+-----+------------+-----------+----------+---------------------+
| 124 | Encino | CA | AAA  | 7   |   1 | 1993-09-01 | allocated |          | 2014-02-26 08:16:07 |
+-----+--------+----+------+-----+-----+------------+-----------+----------+---------------------+

等等。将此表中的“num”字段视为公司ID。

“info”表包含有关某些公司的信息,并将该公司ID用作唯一标识符。并非“记录”中列出的所有公司都将在“信息”中。 “信息”表的一个示例:

mysql> SELECT * FROM info LIMIT 2;
+-----+-------+--------------------------+---------------------+
| org | name  | description              | updated             |
+-----+-------+--------------------------+---------------------+
|   0 | ACME  |                          | 2014-02-19 10:35:39 |
|   1 | AT&T  | Some Phone Company, Inc. | 2014-02-18 15:29:50 |
+-----+-------+--------------------------+---------------------+

所以“org”在这里将匹配第一个表中的“num”。

我希望能够运行一个查询,在一行中返回第一个表中除'id','type'和'val'之外的所有内容,以及IF APPLICABLE,'name'和'description'来自第二个表。

我可以使用此查询实现我想要的目标:

SELECT city,st,num,startdate,status,comments,updated, \
( SELECT name FROM info WHERE org = '7') AS name, \
( SELECT description FROM info WHERE org = '7') AS description \
FROM records WHERE num = '7'

但我发现至少有两个问题:

  1. 运行两个子查询似乎效率低下
  2. 当“info”中没有记录时,将打印名称和的NULL 描述。我想打印一些字符串。
  3. 为了解决第一个问题,我试图返回一个数组。但是当“info”表中没有相应的记录时,我什么也得不到,甚至没有“记录”表中的有效信息。这是我的数组查询:

    SELECT city,st,num,startdate,status,comments,updated,asinfo.name AS name,asinfo.description AS description \
    FROM records, \
    ( SELECT name,description FROM info WHERE org = '7') AS asinfo \
    WHERE num = '7'
    

    如果两个表中都存在给定的公司ID,则此查询可以正常工作。

    为了解决第二个问题,我尝试了各种各样的IFNULL咒语并合并,但无济于事。

    我很感激任何见解。

    感谢。

3 个答案:

答案 0 :(得分:1)

LEFT JOIN表中没有匹配的行时,使用info获取空值。

SELECT city,st,num,startdate,status,comments,updated,
       IFNULL(name, 'Default Name') name, 
       IFNULL(description, 'Default Description') description
FROM records r
LEFT JOIN info i ON r.num = i.org
WHERE r.num = 7

答案 1 :(得分:1)

应用LEFT JOIN语法:

SELECT 
  r.city,
  r.st,
  r.num,
  r.startdate,
  r.status,
  r.comments,
  r.updated,
  IF(d.name IS NULL, 'Default', d.name) AS name,
  IF(d.description IS NULL, 'Default', d.description) AS description
FROM
  records AS r
    LEFT JOIN info AS d ON r.num=d.org
WHERE
  r.num='7'

将以这种方式工作:LEFT JOIN查看第一个表,如果第二个没有相应的记录,则应用NULL。因此,您会发现使用IF(或IFNULL)并替换默认字符串。

答案 2 :(得分:0)

听起来像从记录到信息的简单LEFT JOIN就可以解决这个问题。

LEFT JOIN而不是JOIN,以确保您始终从记录表中获取所有行,如果该ID存在外部参照,则确保信息表中的相应数据。

无论是使用子查询还是使用连接,如果您总是希望查看记录表中的所有行,那么您将始终获取与不存在外部参照的信息表对应的NULL。避免这种情况的唯一方法是运行一些从记录调用所有内容的代码,然后迭代结果以查询信息,有条件地添加到记录数据。