返回不存在的行的默认值

时间:2014-03-01 17:05:09

标签: mysql sql

到最基本的查询

SELECT id, column1, column2
FROM table1
WHERE id IN ("id1", "id2", "id3")

其中where语句中的参数作为变量传递,我还需要为id不存在的行返回值。一般来说,这是一个非常类似的问题,如下所述:SQL: How to return an non-existing row?但是,WHERE语句中有多个参数

当id2不存在时的结果:

-------------------------------
| id  | column1   | column2   |
-------------------------------
| id1 | some text | some text |
| id3 | some text | some text |
-------------------------------

当id2不存在时所需的结果

-----------------------------------
| id  | column1     | column2     |
-----------------------------------
| id1 | some text   | some text   |
| id2 | placeholder | placeholder |
| id3 | some text   | some text   |
-----------------------------------

我的第一个想法是创建一个临时表并将其加入查询。不幸的是,我没有权限创建任何类型的临时表,所以我只能使用SELECT语句。

有没有办法在SQL SELECT查询中执行此操作?

修改 实际上,上面提到的是假设的情况。在WHERE子句中可以有数百个ID,其中缺少的数量是未知的。

3 个答案:

答案 0 :(得分:4)

您可以执行派生表来创建临时表,但它只能用于这一个查询:

SELECT t.id, COALESCE(t.column1, _dflt.column1) AS column1
FROM (
  SELECT 'id1' AS id, 'placeholder text 1' as column1
  UNION ALL
  SELECT 'id2', 'placeholder text 3'
  UNION ALL
  SELECT 'id3', 'placeholder text 3'
) AS _dflt
LEFT OUTER JOIN table1 t USING (id);

评论:

我刚刚在MySQL 5.6.15上测试了上面的方法,看看我可以通过一系列UNION ALL获得多少不同的SELECT,每个SELECT一行。

我得到了派生表以返回5332行,但我想如果我有更多内存,我可以更高。

如果我再试一次UNION ALL,我会得到:ERROR 1064 (42000): memory exhausted near '' at line 10665。我在这个VM上只配置了2.0GB的RAM。

此解决方案无法使用多少ID无关紧要。只需将它们全部放在派生表中即可。通过使用LEFT OUTER JOIN,它会自动查找table1中存在的那些,并且对于缺少的那些,派生表中的条目将与NULL匹配。

COALESCE()函数返回其第一个非null参数,因此如果匹配的行存在,它将使用匹配行中的列。如果找不到,则默认为派生表中的列。

答案 1 :(得分:0)

投影包含所需候选ID的派生表,然后将其连接到它:

select ids.id, coalesce(table1.column1,'placeholder') 
From
(Select 'id1' as id
Union
Select 'id2'
Union
Select 'id3') ids
left join table1
on ids.id1 = table1.id1
and table1.id in (...);

如果要从外部源(例如应用程序)生成候选ids列表,可以将id插入temporary table然后加入它(MySql不支持表)变量)。

答案 2 :(得分:0)

创建一个存储过程,将输入id1,id2等作为输入......

DELIMITER //
CREATE PROCEDURE P1(IN p_in varchar(5))
BEGIN
DECLARE count integer;
SELECT count(id) INTO count FROM TABLE1 
WHERE id = p_in;

IF count = 1 THEN
    SELECT * from table1 where id = p_in;
ELSE
    select p_id, 'some text', 'some text';
END IF;
END//

DELIMITER ;

调用程序获得所需的输出..

CALL P1('id1'); 
CALL P2('id2'); 

..等等你的程序......