TSQL: का चयन माता-पिता पर आधारित स्थिति पर बच्चे

0

सवाल

मैं एक माता पिता की मेज Orders और एक बच्चे की मेज Jobs निम्न नमूना डेटा enter image description here

मैं करने के लिए चाहते हैं का चयन करें आदेश के आधार पर निम्न आवश्यकताओं

1>प्रत्येक आदेश के लिए वहाँ हो सकता है 0 या अधिक नौकरियों. का चयन नहीं करते आदेश अगर यह नहीं करता है किसी भी काम किया है.
2>एक उपयोगकर्ता नहीं कर सकते काम पर अधिक से अधिक एक नौकरी के अंतर्गत आता है कि एक ही क्रम में ।
उदाहरण के लिए उपयोगकर्ता 1 पर काम नहीं कर सकता है कि नौकरियों के अंतर्गत आता है ऑर्डर करने के लिए 1 और 2 क्योंकि वह पहले से ही नौकरियों पर काम 1 और 4 से एक ही आदेश है.
3>केवल आदेश का चयन किया है कि नौकरियों में Requested स्थिति

मैं निम्न क्वेरी देता है कि मुझे उम्मीद परिणाम

DECLARE @UserID INT = 2

SELECT O.OrderID
FROM Orders O
JOIN Jobs J ON J.OrderID = O.OrderID
WHERE 
J.JobStatus = 'Requested' AND
NOT EXISTS
(  
    --Must not have worked this Order
    SELECT 1 FROM Jobs J1
    WHERE J1.OrderID = O.OrderID AND J1.UserID = @UserID
)
Group By o.OrderID

SQL बेला डेमो

क्वेरी में मिलती है Jobs तालिका में दो बार. मैं कोशिश कर रहा हूँ का अनुकूलन करने के लिए क्वेरी और एक रास्ते की तलाश को प्राप्त करने के लिए उम्मीद परिणाम का उपयोग करके Jobs तालिका में केवल एक बार यदि संभव हो तो. किसी भी अन्य समाधान की भी सराहना की है. मैं बदल सकते हैं तालिका स्कीमा यदि आवश्यक हो.

नौकरियों तालिका में लगभग 20 मीटर पंक्तियों और कुछ समय क्वेरी खराब प्रदर्शन से पता चलता है. (हाँ, हम पर देखा अनुक्रमित). मुझे लगता है कि इसकी स्कैनिंग नौकरियाँ टेबल पर दो बार प्रदर्शन समस्या पैदा कर रहा.

2

सबसे अच्छा जवाब

1

यदि उद्देश्य है करने के लिए बस का उपयोग करें "नौकरियाँ तालिका में केवल एक बार", मैं कुछ करने की कोशिश की तरह:

DECLARE @UserID INT = 2
    
SELECT 
    O.OrderID
FROM 
    Orders O
    INNER JOIN Jobs J ON J.OrderID = O.OrderID  
GROUP BY
    O.OrderID
HAVING
    SUM(CASE WHEN J.JobStatus = 'Requested' THEN 1 ELSE 0 END) > 0
    AND SUM(CASE WHEN J.UserID = @UserId THEN 1 ELSE 0 END) = 0

SQL बेला

अनुकूलन करने के लिए इसके अलावा, मैं सुझाव है की जगह varchar डेटा प्रकार की JobStatus स्तंभ के साथ tinyint एक (बनाने के लिए और एक JobStatuses तालिका). एक बार अपने Job तालिका में 20 मीटर रिकॉर्ड है, तो varchar(10) आप 190 एमबी, हालांकि का उपयोग कर tinyint को कम कर देता स्तंभ का आकार के लिए 19 Mb — यह आप कम IO-पढ़ने के संचालन ।

और मैं अलग करने की कोशिश बच्चे को छानने में शामिल होने से यह माता-पिता के साथ. इस तरह के दृष्टिकोण का उपयोग कर सकते हैं कम स्मृति के लिए एक ही आपरेशन और जीत में प्रदर्शन की वजह से है कि:

DECLARE @UserID INT = 2
DECLARE @OrderIDs TABLE (OrderID INT NOT NULL PRIMARY KEY)

INSERT IGNORE INTO @OrderIDs
SELECT
    OrderID
FROM
    Jobs
GROUP BY
    OrderID
HAVING
    SUM(CASE WHEN JobStatus = 'Requested' THEN 1 ELSE 0 END) > 0
    AND SUM(CASE WHEN UserID = @UserId THEN 1 ELSE 0 END) = 0

SELECT
    O.*
FROM
    Orders O
    INNER JOIN @OrderIDs ids on ids.OrderID = O.OrderID
2021-11-16 09:14:13

नौकरी की स्थिति है, वास्तव में ID int प्रकार के. बस समझने के लिए उद्देश्य मैं रखा यह के रूप में nvarchar
LP13

इस दृष्टिकोण के साथ, देखो की तरह मैं भी नहीं है में शामिल होने के लिए आदेश के साथ तालिका. मैं सीधे उपयोग कर सकते हैं नौकरियाँ प्राप्त करने के लिए तालिका OrderID
LP13
0

आप पर विचार हो सकता है निम्न जोड़ने के लिए सूचकांक के Jobs तालिका:

CREATE INDEX idx_jobs ON Jobs (OrderID, UserID, JobStatus);

इस सूचकांक में, अगर इस्तेमाल किया जाना चाहिए, गति के साथ नहीं मौजूद है सबक्वेरी में आपकी क्वेरी से ऊपर. इसके अलावा, यह कर सकते हैं के लिए इस्तेमाल किया जा में शामिल होने से Orders करने के लिए Jobs में बाहरी शीर्ष स्तर क्वेरी (यद्यपि SQL सर्वर शायद करने के लिए होगा एक सूचकांक स्कैन).

2021-11-16 08:40:46

अन्य भाषाओं में

यह पृष्ठ अन्य भाषाओं में है

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

इस श्रेणी में लोकप्रिय

लोकप्रिय सवाल इस श्रेणी में