Получить аргументы отсутствия существования оператора SQL IN

У меня есть следующий SQL-запрос:

SELECT column FROM table WHERE column IN ('item1','item2','item3')

его результат содержит item1 и item2. Как я могу получить аргумент отсутствия (item3)?
Возможно ли это?

EDIT: у меня есть массив элементов. каждую минуту в массив добавляются новые элементы. Поэтому я должен получить новые элементы, которые являются новыми и не существуют в таблице. После этого я могу выполнить свой процесс и вставить новые элементы в таблицу.

Спасибо


person ShayanKM    schedule 08.02.2015    source источник
comment
Что такое non existence argument?   -  person dotnetom    schedule 08.02.2015
comment
Вы должны четко понимать это. Вы хотите добавить столбец с элементом 3?   -  person szakwani    schedule 08.02.2015
comment
@dotnetom в этом примере это item3   -  person ShayanKM    schedule 08.02.2015
comment
удалить пункт 3 при условии   -  person Ega    schedule 08.02.2015
comment
@ShayanKM Тем не менее это не объясняет, что вы имеете в виду? Вы хотите добавить образец данных и ожидаемые результаты, чтобы мы могли понять, чего вы пытаетесь достичь?   -  person dotnetom    schedule 08.02.2015
comment
@szakwani Ну, у меня есть массив элементов, и я хочу получить список новых элементов, которых нет в таблице.   -  person ShayanKM    schedule 08.02.2015


Ответы (4)


Следующий запрос вернет элементы, которых нет в MyTable:

WITH B
AS
(
    SELECT 'Item1' AS col
    UNION ALL
    SELECT 'Item2' 
    UNION ALL
    SELECT 'Item3' 

)
SELECT B.col
FROM B
WHERE
    NOT EXISTS (
        SELECT *
        FROM MyTable T
        WHERE
            T.col = B.col
    )

РЕДАКТИРОВАТЬ. Из-за того, что создание такого оператора select на стороне клиента может быть утомительным и опасным, вам следует позаботиться о проблемах внедрения и форматирования sql, я предлагаю вам использовать функцию с табличным значением, например следующую:

CREATE TABLE Items
(
    item nvarchar(128) PRIMARY KEY
)

GO

CREATE FUNCTION GetNonExistingItems( @Items xml )
RETURNS TABLE
AS RETURN
WITH B
AS
(
    SELECT c.value('.', 'nvarchar(128)') As item
    FROM @items.nodes('items/item') T(c)
)
SELECT B.item
FROM B
WHERE
    NOT EXISTS (
        SELECT *
        FROM Items I
        WHERE B.item = i.item

    )

GO

DECLARE @items XML = N'
<items>
    <item>Item1</item>
    <item>Item2</item>
    <item>Item5</item>
</items>'

SELECT *
FROM GetNonExistingItems (@Items)
person Jesús López    schedule 08.02.2015
comment
Спасибо! Это сработало... это чем-то похоже на то, что написал @Giorgi_Nakeuri. но я не уверен в производительности этих запросов, это лучший способ? - person ShayanKM; 08.02.2015
comment
Производительность аналогична (если не равна) LEFT JOIN WHERE MyTable.col IS NULL, - person Jesús López; 08.02.2015

Вы можете сделать это, если переведете свой массив в таблицу следующим образом:

Select * From 
( select 'item1' As Column
  union
  select 'item2' As Column
  union
  select 'item3' As Column
) l
left join Table t on l.Column = t.Column
Where t.Column is NULL

Версия без союза:

Select * From 
    ( VALUES
      ('Item1'),
      ('Item2'),
      ('Item3')  
    ) As l(Column)
    left join Table t on l.Column = t.Column
    Where t.Column is NULL
person Giorgi Nakeuri    schedule 08.02.2015
comment
Это сделало работу, но я думаю, что использование union select вместо IN убьет мою производительность ... Нет ли другого лучшего способа? - person ShayanKM; 08.02.2015
comment
Проверить новую версию выписки - person Giorgi Nakeuri; 08.02.2015

Прочитав ваше редактирование, я могу предложить вам следующий подход. Поскольку вы хотите вставить несуществующие элементы в таблицу, я думаю, вы могли бы сделать это в одном операторе слияния.

Учитывая следующую таблицу:

CREATE TABLE Items
(
    item nvarchar(128) PRIMARY KEY
)

Вы можете передать новые элементы в массиве в форме xml следующей хранимой процедуре:

CREATE PROCEDURE InsertIfNotExists @Items xml
AS
    WITH B
    AS
    (
        SELECT c.value('.', 'nvarchar(128)') As item
        FROM @items.nodes('items/item') T(c)
    )
    MERGE INTO Items I
    USING B ON B.Item = I.Item
    WHEN NOT MATCHED BY TARGET THEN
    INSERT (Item) VALUES (Item);

GO

Здесь у вас есть пример выполнения:

DECLARE @items XML = N'
<items>
    <item>Item1</item>
    <item>Item2</item>
    <item>Item3</item>
    <item>Item4</item>
</items>'

EXEC InsertIfNotExists @items

Другой альтернативой для передачи элементов в хранимую процедуру является использование параметра с табличным значением вместо xml.

person Jesús López    schedule 08.02.2015
comment
Спасибо за внимание к редактированию и +1. Но у меня есть процесс .NET между запросами выбора и вставки, поэтому их не следует объединять. - person ShayanKM; 08.02.2015
comment
Хорошо, я отредактировал свой предыдущий ответ, чтобы предоставить вам то, что я считаю лучшим подходом. - person Jesús López; 08.02.2015

сделайте прок, чтобы вернуть все существование, затем сделайте это

SELECT column FROM table WHERE column NOT IN(your proc );
person Ega    schedule 08.02.2015