为IN列表中的缺失值返回NULL

时间:2014-04-28 07:52:47

标签: mysql sql

我有一张这样的表:

 id | val
 ---------
  1 | abc
  2 | def
  5 | xyz
  6 | foo
  8 | bar

和像

这样的查询
 SELECT id, val FROM tab WHERE id IN (1,2,3,4,5)

返回

 id | val
 ---------
  1 | abc
  2 | def
  5 | xyz

有没有办法让它在缺少的ID上返回NULL,即

 id | val
 ---------
  1 | abc
  2 | def
  3 | NULL
  4 | NULL
  5 | xyz

我想自己应该有一个棘手的LEFT JOIN,但不能绕过它。

编辑:我看到人们在想我想填补空白"在序列中,但实际上我想要的是将NULL替换为IN列表中的缺失值。例如,这个

 SELECT id, val FROM tab WHERE id IN (1,100,8,200)

应该返回

 id | val
 ---------
  1 | abc
100 | NULL
  8 | bar
200 | NULL

此外,订单并不重要。

EDIT2:只需添加几个相关链接:

2 个答案:

答案 0 :(得分:1)

你可以使用这个技巧:

SELECT v.id, t.val
FROM
  (SELECT 1 AS id
   UNION ALL SELECT 2
   UNION ALL SELECT 3
   UNION ALL SELECT 4
   UNION ALL SELECT 5) v
  LEFT JOIN tab t
  ON v.id = t.id

请参阅小提琴here

答案 1 :(得分:1)

是的,你可以。但这很棘手,因为MySQL中有 no sequences

我假设您只想要任何选择,所以它是:

SELECT
  *
FROM
  (SELECT
   (two_1.id + two_2.id + two_4.id + 
   two_8.id + two_16.id) AS id
   FROM
   (SELECT 0 AS id UNION ALL SELECT 1 AS id) AS two_1
   CROSS JOIN (SELECT 0 id UNION ALL SELECT 2 id) AS two_2
   CROSS JOIN (SELECT 0 id UNION ALL SELECT 4 id) AS two_4
   CROSS JOIN (SELECT 0 id UNION ALL SELECT 8 id) AS two_8
   CROSS JOIN (SELECT 0 id UNION ALL SELECT 16 id) AS two_16
   ) AS sequence
  LEFT JOIN
    t
    ON sequence.id=t.id
WHERE
  sequence.id IN (1,2,3,4,5);

(check the fiddle)

它将作为2的幂的组合工作,以生成连续的数字表。您的值将传递给WHERE子句,因此您可以替换任何一组值。

我建议你在这种情况下使用应用程序 - 因为它会更快。如果你想在其他地方使用这个行集(也就是在其他一些查询中),可能会有一些意义 - 但如果不是,那么它就是你应用程序的工作。

如果您需要更高的值,请向序列生成器添加更多行,例如此fiddle