2017-02-08 4 views
0

Я хочу удалить из t2, если одно значение itemid, storeid, MSRTime не существует на t1, и то же значение itemid, storeid, MSRTime существует на t3, а статус - D. В приведенном ниже примере я должен иметь возможность удалить вторую строку на t2, но не первую строку.SQL Server: Удалить из таблицы на основе значения другой таблицы

Таблица 1: t1

itemid |storeid|MSRTime 
x  y  z 

Таблица 2: t2

itemid |storeid|MSRTime 
    x  y  z 
    a  b  c 

Таблица 3: t3

itemid |storeid|MSRTime|status 
    x  y  z D 
    a  b  c D 

Я попытался сделать это с помощью присоединиться, но я не мог достичь желаемого результат. Пожалуйста помоги.
Спасибо.

ответ

1

Вы можете написать запрос почти точно так, как вы описали его:

declare @t1 table(itemid varchar(7),storeid varchar(9),MSRTime varchar(3)) 
insert into @t1(itemid,storeid,MSRTime) values 
('x','y','z') 
declare @t2 table(itemid varchar(7),storeid varchar(9),MSRTime varchar(3)) 
insert into @t2(itemid,storeid,MSRTime) values 
('x','y','z'), 
('a','b','c') 
declare @t3 table(itemid varchar(7),storeid varchar(9),MSRTime varchar(3),status varchar(4)) 
insert into @t3(itemid,storeid,MSRTime,status) values 
('x','y','z','D'), 
('a','b','c','D') 

delete from t2 
from @t2 t2 
    inner join 
    @t3 t3 
     on 
      t2.itemid = t3.itemid and 
      t2.storeid = t3.storeid and 
      t2.MSRTime = t3.MSRTime and 
      t3.status = 'D' 
where 
    not exists (
     select * 
     from @t1 t1 
     where t1.itemid = t2.itemid and 
      t1.storeid = t2.storeid and 
      t1.MSRTime = t2.MSRTime 
    ) 

select * from @t2 

Результат:

itemid storeid MSRTime 
------- --------- ------- 
x  y   z 
+0

Я думаю, что это могло бы работать для меня. Благодарим вас за помощь. Я приму ответ, когда проверю его на моем реальном сценарии. – Amir

+0

Спасибо, что это сработало как очарование для меня. – Amir

0

Должно быть что-то вроде этого

-- delete t2 
select * 
from table2 t2 
JOIN table3 t3 on t2.itemid = t3.itemid and 
        t2.storeid = t3.storeid and 
        t2.MSRTime = t3.MSRTime 
LEFT JOIN table1 t1 on t2.itemid = t1.itemid and 
         t2.storeid = t1.storeid and 
         t2.MSRTime = t1.MSRTime 
where t1.itemID IS NULL 

Запустить выберите первый, если он дает задний правый ряд, просто не по-комментарий удалить, и вы хорошо идти

0

Я создал весь скрипт для вашей справки. Пожалуйста, используйте последний запрос DELETE для вашего сценария. Это сделает трюк.

CREATE TABLE #T1 
(itemid VARCHAR(10) 
,storeid VARCHAR(10) 
,MSRTime VARCHAR(10)) 

INSERT INTO #T1 VALUES ('x','y','z') 

SELECT * FROM #T1 

GO 

CREATE TABLE #T2 
(itemid VARCHAR(10) 
,storeid VARCHAR(10) 
,MSRTime VARCHAR(10)) 

INSERT INTO #T2 VALUES ('x','y','z'),('a','b','c') 

SELECT * FROM #T2 

GO 

CREATE TABLE #T3 
(itemid VARCHAR(10) 
,storeid VARCHAR(10) 
,MSRTime VARCHAR(10) 
,status VARCHAR(10)) 

INSERT INTO #T3 VALUES ('x','y','z','D'),('a','b','c','D') 

SELECT * FROM #T3 

GO 

DELETE M 
FROM #T2 AS M INNER JOIN 
(SELECT itemid,storeid,MSRTime FROM 
(SELECT itemid,storeid,MSRTime FROM #T3 WHERE status='D') T1 
INTERSECT 
(SELECT itemid,storeid,MSRTime FROM 
      (SELECT * FROM #T2 
      EXCEPT 
      SELECT * FROM #T1) T2)) X 
ON X.itemid = M.itemid AND X.storeid = M.storeid AND X.MSRTime = M.MSRTime   

GO 
0

Не уверен, если это соответствует вашей среде, но программно это может быть полезно, чтобы ограничить результаты, которые вы сравниваете с стыки только те, которые имеют значение D в состоянии. Я также попробую сделать сложный ключ, используя Coalese, чтобы вам не приходилось сопоставлять три отдельных соединения.

Например -

itemid |storeid|MSRTime|Key x y z xyz a b c abc

+0

Благодарим за предложение. Но этот пример был общим представлением моей проблемы. Есть и другие поля, которые мне нужно проверить. – Amir

+0

Почему вы не можете просто использовать функцию AND в соединении для соответствия IE DELETE t2 FROM table2 t2 INNER JOIN table1 t1 ON t1.itemid = t2.itemid AND t1.storied = t2.storied AND t1.MSRTime = t2. MSRTime –