SQL如何从列表中查找不在表中的值

时间:2014-03-14 09:25:00

标签: sql sqlite

我在一个名为' code'。

的字段中有一个包含值的表
ABC
DFG
CDF

如何从列表中选择表中没有的所有代码? 例如:

SELECT * from [my list] where table1.code not in [my list]

列表不在表格中。

列表类似于"ABC","BBB","TTT"(作为字符串)

5 个答案:

答案 0 :(得分:3)

试试这个:

SELECT code 
FROM Table1
WHERE code NOT IN ('ABC','CCC','DEF') --values from your list

结果是:

DFG
CDF

如果列表在另一个表中,请尝试:

SELECT code 
FROM Table1
WHERE code NOT IN (SELECT code FROM Table2)

根据您的要求,试试这个:

SELECT list
FROM Table2
WHERE list NOT IN (SELECT code from table1)

它将选择不在代码中的列表值。 请参阅SQL Fiddle

中的示例

答案 1 :(得分:1)

你能使用公用表表达式吗?

WITH temp(code) AS (VALUES('ABC'),('BBB'),('TTT'),(ETC...))
SELECT temp.code FROM temp WHERE temp.code NOT IN 
(SELECT DISTINCT table1.code FROM table1); 

这将允许您创建一个使用VALUES语句中的字符串列表定义的临时表。然后使用标准SQL在table1.code列中选择NOT NOT值。

答案 2 :(得分:1)

问题关键点需要将"ABC","BBB","TTT"源数据trun设置为表格。

该表格看起来像

|---+
|val|
|---+
|ABC|
|BBB|
|TTT|

Sqlite不支持sqlite功能。因此,sqlite您的列表很难成为一张桌子。

您可以使用CTE Recursive制作sqlite功能

  1. 您需要使用replace功能删除您的"双引号 来源数据。
  2. CTE中有两列
    • val列带有您的列表数据
    • rest列,以便记住当前的splite字符串
  3. 你会得到CTE这样的表格。

    |---+
    |val|
    |---+
    |ABC|
    |BBB|
    |TTT|
    

    然后,您可以将数据与table1进行比较。

    不在

    WITH RECURSIVE split(val, rest) AS (
        SELECT '',  replace('"ABC","BBB","TTT"','"','') || ',' 
        UNION ALL
        SELECT  
             substr(rest, 0, instr(rest, ',')),
             substr(rest, instr(rest, ',')+1)
        FROM split
        WHERE rest <> '')
    SELECT * from (
      SELECT val
      FROM split 
      WHERE val <> ''
    ) t where t.val not IN (
      select t1.code 
      from table1 t1
    )
    

    sqlfiddle:https://sqliteonline.com/#fiddle-5adeba5dfcc2fks5jgd7ernq

    Outut结果:

    +---+
    |val|
    +---+
    |BBB|
    |TTT|
    

    如果要在一行中显示,请使用GROUP_CONCAT功能。

    WITH RECURSIVE split(val, rest) AS (
        SELECT '',  replace('"ABC","BBB","TTT"','"','') || ',' 
        UNION ALL
        SELECT  
             substr(rest, 0, instr(rest, ',')),
             substr(rest, instr(rest, ',')+1)
        FROM split
        WHERE rest <> '')
    SELECT GROUP_CONCAT(val,',') val from (
      SELECT val
      FROM split 
      WHERE val <> ''
    ) t where t.val not IN (
      select t1.code 
      from table1 t1
    )
    

    Outut结果:

    BBB, TTT
    

    sqlfiddle:https://sqliteonline.com/#fiddle-5adecb92fcc36ks5jgda15yq

    注意:这在SELECT * from [my list] where table1.code not in [my list]上是不合理的,因为此查询无法找到table1,因此您无法获得table1.code

    您可以使用not existsJOIN来实现您的期望。

    sqlfiddle:https://sqliteonline.com/#fiddle-5adeba5dfcc2fks5jgd7ernq

答案 3 :(得分:0)

这个解决方案是好的,还是我错过了什么?

create table table10 (code varchar(20));

insert into table10 (code) values ('ABC');
insert into table10 (code) values ('DFG');
insert into table10 (code) values ('CDF');

select * from (
  select 'ABC' as x
  union all select 'BBB'
  union all select 'TTT'
) t where t.x not in (select code from table10);
-- returns: BBB
--          TTT

请参阅SQL Fiddle

答案 4 :(得分:0)

这也可以使用存储过程来实现:

DELIMITER //
drop function if exists testcsv
//
create function testcsv(csv varchar(255)) returns varchar(255)
deterministic
begin
    declare pos, found int default 0;
    declare this, notin varchar(255);
    declare continue handler for not found set found = 0;

    set notin = '';
    repeat
        set pos = instr(csv, ',');
        if (pos = 0) then
            set this = trim('"' from csv);
            set csv = '';
        else
            set this = trim('"' from trim(substring(csv, 1, pos-1)));
            set csv = substring(csv, pos+1);
        end if;
        select 1 into found from table1 where code = this;
        if (not found) then
            if (notin = '') then
                set notin = this;
            else
                set notin = concat(notin, ',', this);
            end if;
        end if;
        until csv = ''
    end repeat;
    return (notin);
end
//
select testcsv('"ABC","BBB","TTT","DFG"')

输出:

BBB, TTT
相关问题