टी-एसक्यूएल: जुड़ने के माध्यम से हटाने के लिए पंक्तियों का चयन करना


494

परिदृश्य:

मान लीजिए कि मेरे पास दो टेबल हैं, टेबलए और टेबलबी। TableB की प्राथमिक कुंजी एक एकल स्तंभ (BId) है, और TableA में एक विदेशी कुंजी स्तंभ है।

मेरी स्थिति में, मैं TableB में सभी पंक्तियों को हटाना चाहता हूं जो TableB में विशिष्ट पंक्तियों के साथ जुड़ी हुई हैं: क्या मैं इसे जॉइन कर सकता हूं? उन सभी पंक्तियों को हटा दें, जो जोड़ से खींची जाती हैं?

DELETE FROM TableA 
FROM
   TableA a
   INNER JOIN TableB b
      ON b.BId = a.BId
      AND [my filter condition]

या मैं ऐसा करने के लिए मजबूर हूं:

DELETE FROM TableA
WHERE
   BId IN (SELECT BId FROM TableB WHERE [my filter condition])

मेरे द्वारा पूछे जाने का कारण यह है कि मुझे लगता है कि बड़े तालिकाओं के साथ काम करते समय पहला विकल्प बहुत अधिक आकर्षक होगा।

धन्यवाद!

जवाबों:


722
DELETE TableA
FROM   TableA a
       INNER JOIN TableB b
               ON b.Bid = a.Bid
                  AND [my filter condition] 

कार्य करना चाहिए


1
मैंने एक खंड के बजाय जॉइन पर [और मेरी फ़िल्टर स्थिति] का उपयोग किया। मैं कल्पना करूंगा कि दोनों काम करेंगे, लेकिन ज्वाइन पर फिल्टर की स्थिति में शामिल होने से आपके परिणाम सीमित हो जाएंगे।
theTXI

10
एक सवाल। हमें E DELETE FROM ’के बजाय ET DELETE TableA FROM’ लिखने की आवश्यकता क्यों है? मैं देखता हूं कि यह केवल इस मामले में काम करता है, लेकिन क्यों?
लाब्राका

66
मुझे लगता है क्योंकि आपको रिकॉर्ड को हटाने के लिए किस तालिका को इंगित करना है। मैंने सिंटैक्स के साथ एक क्वेरी चलाई DELETE TableA, TableB ...और वास्तव में दोनों से प्रासंगिक रिकॉर्ड हटा दिए। अच्छा लगा।
एंड्रयू

1
PostgreSQL सिंटैक्स में शामिल होने से काम नहीं होता है लेकिन "कीवर्ड" का उपयोग करना संभव है। DELETE from TableA a using TableB b where b.Bid = a.Bid and [my filter condition]
बारटोलो-ओटिट

8
MySQL में आपको MULTI DELETE में "अज्ञात तालिका 'TableA' एक त्रुटि मिलेगी और ऐसा इसलिए है क्योंकि आपने TableA (a) के लिए एक उपनाम घोषित किया है। छोटा समायोजन:DELETE a FROM TableA a INNER JOIN TableB b on b.Bid = a.Bid and [my filter condition]
मस्तूल

260

मैं इस वाक्यविन्यास का उपयोग करूंगा

Delete a 
from TableA a
Inner Join TableB b
on  a.BId = b.BId
WHERE [filter condition]

7
मैं इस वाक्यविन्यास को पसंद करता हूं, लगता है कि तार्किक रूप से थोड़ा अधिक समझ में आता है कि क्या चल रहा है। इसके अलावा, मुझे पता है कि आप एक UPDATE के लिए इसी प्रकार के सिंटैक्स का उपयोग कर सकते हैं।
एडम नोफ़्सिंगर

मैं इसे भी पसंद करता हूं, क्योंकि DELETE के बाद टेबल उर्फ ​​का प्लेसमेंट हमेशा मेरे लिए अधिक सहज लगता है जैसे कि डिलीट किया जा रहा है।
जगद

14
वास्तव में, यह मेरे लिए भी पसंद किया जाता है। विशेष रूप से उन मामलों में जहां मुझे वास्तव में एक ही तालिका में शामिल होने की आवश्यकता है (उदाहरण के लिए डुप्लिकेट रिकॉर्ड हटाने के लिए)। उस स्थिति में, मुझे उस "पक्ष" के लिए एक उपनाम का उपयोग करने की आवश्यकता है जिसे मैं हटा रहा हूं और यह वाक्यविन्यास यह स्पष्ट करता है कि मैं डुप्लिकेट उपनाम से हटा रहा हूं।
क्रिस सिमंस

29

हाँ तुम कर सकते हो। उदाहरण :

DELETE TableA 
FROM TableA AS a
INNER JOIN TableB AS b
ON a.BId = b.BId
WHERE [filter condition]

8
मैं इसके उपनाम से पहली पंक्ति में तालिका को संदर्भित करना पसंद करता हूं। वह है "डिलीट टेबलए" के बजाय "डिलीट"। उस स्थिति में जहां आप तालिका को खुद से जोड़ते हैं, यह स्पष्ट करता है कि आप किस पक्ष को हटाना चाहते हैं।
जेरेमी स्टीन

10

एक एक्सेस डेटाबेस के साथ ऐसा करने की कोशिश कर रहा था और मैंने पाया कि डिलीट होने के बाद *

DELETE a.*
FROM TableA AS a
INNER JOIN TableB AS b
ON a.BId = b.BId
WHERE [filter condition]

अस्वीकृत लंबित संपादन से: "UniqueRecords की प्रॉपर्टी को हां में सेट करना होगा, अन्यथा यह काम नहीं करेगा। ( support.microsoft.com/kb/240098 )"
स्टॉपरवेयर

8

यह MySQL में लगभग समान है , लेकिन आपको "DELETE" शब्द के ठीक बाद टेबल उपनाम का उपयोग करना होगा।

DELETE a
FROM TableA AS a
INNER JOIN TableB AS b
ON a.BId = b.BId
WHERE [filter condition]

2

उपर्युक्त वाक्यविन्यास इंटरबेस 2007 में काम नहीं करता है। इसके बजाय, मुझे कुछ इस तरह का उपयोग करना पड़ा:

DELETE FROM TableA a WHERE [filter condition on TableA] 
  AND (a.BId IN (SELECT a.BId FROM TableB b JOIN TableA a 
                 ON a.BId = b.BId 
                 WHERE [filter condition on TableB]))

(नोट Interbase उपनामों के लिए AS कीवर्ड का समर्थन नहीं करता है)


2

मैं यह प्रयोग कर रहा हूं

DELETE TableA 
FROM TableA a
INNER JOIN
TableB b on b.Bid = a.Bid
AND [condition]

और @TheTXI का तरीका काफी अच्छा है, लेकिन मैंने जवाब और टिप्पणियां पढ़ीं और मैंने पाया कि जिन चीजों का जवाब दिया जाना चाहिए, वह शर्त है कि WHERE क्लॉज में शर्त का इस्तेमाल किया जा रहा है। इसलिए मैंने इसका परीक्षण करने और एक स्निपेट लिखने का फैसला किया, लेकिन उनके बीच एक सार्थक अंतर नहीं मिला। आप यहां एसक्यूएल स्क्रिप्ट देख सकते हैं और महत्वपूर्ण बात यह है कि मैंने इसे कॉमनेट के रूप में लिखना पसंद किया क्योंकि यह सटीक उत्तर नहीं है, लेकिन यह बड़ा है और टिप्पणियों में नहीं डाला जा सकता है, कृपया मुझे क्षमा करें।

Declare @TableA  Table
(
  aId INT,
  aName VARCHAR(50),
  bId INT
)
Declare @TableB  Table
(
  bId INT,
  bName VARCHAR(50)  
)

Declare @TableC  Table
(
  cId INT,
  cName VARCHAR(50),
  dId INT
)
Declare @TableD  Table
(
  dId INT,
  dName VARCHAR(50)  
)

DECLARE @StartTime DATETIME;
SELECT @startTime = GETDATE();

DECLARE @i INT;

SET @i = 1;

WHILE @i < 1000000
BEGIN
  INSERT INTO @TableB VALUES(@i, 'nameB:' + CONVERT(VARCHAR, @i))
  INSERT INTO @TableA VALUES(@i+5, 'nameA:' + CONVERT(VARCHAR, @i+5), @i)

  SET @i = @i + 1;
END

SELECT @startTime = GETDATE()

DELETE a
--SELECT *
FROM @TableA a
Inner Join @TableB b
ON  a.BId = b.BId
WHERE a.aName LIKE '%5'

SELECT Duration = DATEDIFF(ms,@StartTime,GETDATE())

SET @i = 1;
WHILE @i < 1000000
BEGIN
  INSERT INTO @TableD VALUES(@i, 'nameB:' + CONVERT(VARCHAR, @i))
  INSERT INTO @TableC VALUES(@i+5, 'nameA:' + CONVERT(VARCHAR, @i+5), @i)

  SET @i = @i + 1;
END

SELECT @startTime = GETDATE()

DELETE c
--SELECT *
FROM @TableC c
Inner Join @TableD d
ON  c.DId = d.DId
AND c.cName LIKE '%5'

SELECT Duration    = DATEDIFF(ms,@StartTime,GETDATE())

यदि आप इस स्क्रिप्ट से अच्छा कारण प्राप्त कर सकते हैं या एक और उपयोगी लिख सकते हैं, तो कृपया साझा करें। धन्यवाद और इस मदद की उम्मीद है।


1

मान लें कि आपके पास 2 तालिकाएँ हैं, एक मास्टर सेट के साथ (जैसे। कर्मचारी) और एक बच्चे के सेट के साथ (जैसे। आश्रित) और आप डिपेंडेंट टेबल में डेटा की सभी पंक्तियों से छुटकारा पाना चाहते हैं जो कुंजी नहीं कर सकते। मास्टर तालिका में किसी भी पंक्तियों के साथ।

delete from Dependents where EmpID in (
select d.EmpID from Employees e 
    right join Dependents d on e.EmpID = d.EmpID
    where e.EmpID is null)

यहाँ ध्यान देने वाली बात यह है कि आप केवल पहले से जुड़ने से EmpIDs का एक 'सरणी' एकत्र कर रहे हैं, जो कि EmpIDs के उस सेट का उपयोग करके डिपेंडेंट टेबल पर एक डिलीट ऑपरेशन करते हैं।


1

SQLite में, केवल एक चीज जो काम करती है, वह beauXjames के उत्तर के समान है।

ऐसा लगता है DELETE FROM table1 WHERE table1.col1 IN (SOME TEMPORARY TABLE); कि यह नीचे आ गया है और कुछ अस्थायी तालिका को SELECT द्वारा क्रेट किया जा सकता है और अपनी दो तालिका को जोड़ सकते हैं जिसे आप इस अस्थायी तालिका को उस स्थिति के आधार पर फ़िल्टर कर सकते हैं जिसे आप Table1 में रिकॉर्ड हटाना चाहते हैं।


1

आप इस क्वेरी को चला सकते हैं: -

Delete from TableA 
from 
TableA a, TableB b 
where a.Bid=b.Bid
AND [my filter condition]


1
DELETE FROM table1
where id IN 
    (SELECT id FROM table2..INNER JOIN..INNER JOIN WHERE etc)

सम्मिलित होने के साथ DML प्रश्नों का उपयोग कम से कम करें। आपको उपर्युक्त सभी उपखंडों के साथ डीएमएल के अधिकांश प्रश्नों को करने में सक्षम होना चाहिए।

सामान्य तौर पर, जॉइन का उपयोग केवल तब किया जाना चाहिए जब आपको 2 या अधिक तालिकाओं में स्तंभों द्वारा चयन या समूह की आवश्यकता हो। यदि आप केवल एक जनसंख्या को परिभाषित करने के लिए कई तालिकाओं को छू रहे हैं , तो उपश्रेणियों का उपयोग करें। DELETE प्रश्नों के लिए, सहसंबद्ध उपश्रेणी का उपयोग करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.