2016-03-26 13 views
6

मैं एक प्रश्न एक संग्रहीत प्रक्रिया एक एकल पैरामीटर है कि में निम्नलिखित के स्वरूप के समान है:सशर्त छानने में शामिल हों

SELECT 
    ID, 
    DepartmentID, 
    FileName 
FROM 
    Document 
-- conditional join from here 
JOIN 
    AllowedDepartmentList ON DepartmentID = AllowedDepartmentList.ID 
          AND @IsAdmin = 'false' 

पैरामीटर डेटा प्रकार बिट के साथ @IsAdmin है।

मैं जिन दो टेबलों के साथ काम करता हूं वह Document तालिका (ऊपर क्वेरी में संरचना देखें), और AllowedDepartmentList जिसमें एक int कॉलम है।

मैं इस क्वेरी का उपयोग Document तालिका के आने वाले परिणामों को शामिल करने के लिए फ़िल्टर करता हूं। मैं WHERE DepartmentID IN() खंड का उपयोग नहीं करता, क्योंकि आवंटित डिपार्टमेंटलिस्ट 600-700 आइटम (IN() के लिए संभावित रूप से 1 एम रिकॉर्ड तालिका में अच्छे प्रदर्शन के साथ संभालने के लिए बहुत अधिक हो सकता है) तो मैं एक जॉइन का उपयोग करके फ़िल्टर करता हूं, लेकिन फ़िल्टरिंग केवल निष्पादित करें, अगर @IsAdmin पैरामीटर false है। के बाद की लाइनों की तरह - यहां टिप्पणी से सशर्त शामिल भी वहां नहीं थे।

मैंने उपर्युक्त क्वेरी की कोशिश की लेकिन यह कोई रिकॉर्ड नहीं बनाता है। मुझे संदेह है कि मैं गलत प्रकार के शामिल होने का उपयोग कर रहा हूं, लेकिन मैं अटक गया हूं।

उत्तर

3

आप एक बाएं इस्तेमाल कर सकते हैं एक जहां है कि या तो के संयोजन में शामिल होने के व्यवस्थापक विशेषाधिकारों की आवश्यकता है, या पर एक मैच में शामिल होने के

SELECT 
    ID, 
    DepartmentID, 
    FileName 
FROM 
    Document 
-- conditional join from here 
LEFT JOIN 
    AllowedDepartmentList ON DepartmentID = AllowedDepartmentList.ID 
WHERE 
    @IsAdmin = 'true' OR AllowedDepartmentList.ID IS NOT NULL 
+1

ध्यान दें, कि झिल्डन का सुझाव अधिक कुशल है, क्योंकि आप उन परिस्थितियों में शामिल होने से खुद को बचाएंगे जहां इसकी आवश्यकता नहीं है। हालांकि, मैं केवल एक प्रश्न रखने के आपके तर्क को समझता हूं। –

+0

बहुत बहुत धन्यवाद, यह ठीक लगता है, मुझे इसका परीक्षण करना होगा। और हां, आप सही हैं, हमें यह भी जांचना होगा कि अतिरिक्त जुड़ने से इतने सारे ओवरहेड का कारण बनता है कि यह कोड को डुप्लिकेट करने योग्य है। – Daniel

+0

मैंने आपका जवाब स्वीकार कर लिया है क्योंकि हमने परीक्षण उद्देश्यों के लिए इस समाधान को लागू किया है। यह आवश्यकतानुसार काम करता है और काम पूरा हो जाता है, लेकिन प्रदर्शन को मापा जाना चाहिए। बिल के अनुरूप कई अन्य उत्तर हैं, इसलिए मेरी समस्या के साथ समय निकालने वाले सभी लोगों के लिए धन्यवाद। – Daniel

3

एक सामान्य नियम के रूप में, अपने पैरामीटर को WHSE खंडों में शामिल करते हैं। कुछ हद तक सरल समाधान एक टीवीएफ या स्पोक होगा जो दो पूरी तरह से अलग प्रश्नों को चलाता है। कुछ इस तरह:

IF (@isAdmin = 0) --notice I used a SQL bool vs a string of 'false' 
BEGIN 
    SELECT 
     ID, 
     DepartmentID, 
     FileName 
    FROM 
     Document 
    JOIN 
     AllowedDepartmentList ON DepartmentID = AllowedDepartmentList.ID; 
END; 
ELSE 
    [email protected] is not false, so don't join 
    SELECT 
     ID, 
     DepartmentID, 
     FileName 
    FROM 
     Document; 
END; 
+0

यह है कि मैं क्या से बचने के लिए करने की कोशिश की है: चुनिंदा डुप्लिकेट। हमारे एसपी में सटीक चयन बहुत अधिक जटिल है (150 पंक्तियों की तरह) और अगर पूरे शेबांग को डुप्लिकेट किया जाता है तो बहुत बदसूरत हो जाता है ... भविष्य में संशोधन का उल्लेख नहीं करना। – Daniel

+0

@Daniel यदि पूरे शेबांग 150 पंक्तियों को एक कुशल क्वेरी के सभी कारण हैं। प्रतिलिपि पेस्ट कितनी मुश्किल हो सकती है और शामिल हो सकती है? – Paparazzi

+0

आप इस मामले में बिल्कुल सही हैं। सर्वोत्तम जवाब खोजने के लिए हमें वास्तविक डेटा पर कुछ तनाव परीक्षण करना होगा। मैं केवल कोड डुप्लिकेशंस के विकल्प की तलाश में था, लेकिन मुझे इतने सारे अच्छे सुझाव मिलने की उम्मीद नहीं थी (वर्तमान ट्रैक पर रहने सहित, जैसे कि झिल्डन - और आपने सुझाव दिया)। – Daniel

2

निम्न क्वेरी आप

में मदद मिलेगी
SELECT ID 
     ,DepartmentID 
     ,FileName 
FROM Document 
     LEFT JOIN AllowedDepartmentList ON DepartmentID = AllowedDepartmentList.ID 
WHERE @isAdmin = 1 
    OR (@isAdmin = 0 AND AllowedDepartmentList.ID IS NOT NULL) 
3

आप उपयोग कर सकते हालत मौजूद है, इस तरह:

SELECT 
ID, 
DepartmentID, 
FileName 
FROM Document 
WHERE exists(
SELECT 1 from AllowedDepartmentList 
WHERE DepartmentID = AllowedDepartmentList.ID) 
OR @IsAdmin = 'true' 
+0

प्रदर्शन जॉइन से तुलना कैसे करता है? – Daniel

+1

मुझे लगता है कि यह तेज़ है, खासकर यदि आप अतिरिक्त स्थितियों का उपयोग करते हैं, लेकिन आपको कोशिश करनी चाहिए। डेटा प्राप्त करना है, अस्तित्व आपके लिए सही है :) –

+0

जुड़ें रिकॉर्ड गुणा का कारण बन सकता है, मौजूद नहीं है। –

3

Dynamic query का उपयोग करके ऐसा करने का एक और तरीका। यह अच्छा प्रदर्शन जब JOIN/Exists विकल्पों

DECLARE @sql  NVARCHAR(max)='', 
     @IsAdmin BIT = 1 

SET @sql = ' 
SELECT 
    ID, 
    DepartmentID, 
    FileName 
FROM 
    Document D 
    ' + CASE WHEN @IsAdmin = 'false' THEN ' where exists (select 1 from AllowedDepartmentList AD where D.DepartmentID = AD.ID) ' ELSE '' END 

--PRINT @sql 

exec sp_executesql @sql 

गतिशील रूप से तैयार किए क्वेरी की तुलना में जब @IsAdmin = 0

SELECT ID, 
     DepartmentID, 
     FileName 
FROM Document D 
WHERE EXISTS (SELECT 1 
       FROM AllowedDepartmentList AD 
       WHERE D.DepartmentID = AD.ID) 

गतिशील रूप से तैयार किए क्वेरी जब @IsAdmin = 0

SELECT ID, 
     DepartmentID, 
     FileName 
FROM Document D 
1

की तरह का एक AllowedDepartmentList.ID जोड़ने होगा -1 व्यवस्थापक
@admin के लिए शून्य या -1 पास करें आईडी

ON isnull(@adminID, DepartmentID) = AllowedDepartmentList.ID 

एक या (या @IsAdmin = 'सच') कुशल नहीं है और यह भी सिर्फ रिटर्न 1

+0

यह 'विभाग आईडी' –

+0

@Prdp पर मौजूद किसी भी इंडेक्स को मारने जा रहा है, तो मुझे लगता है कि AllowedDepartmentList.ID एक पीके है। यह कम कोड के साथ एक EXISTS से भी बदतर नहीं है। – Paparazzi

संबंधित मुद्दे