2010-04-16 16 views
24

मेरे पास नाम और पते की एक तालिका है, जिसमें एक पोस्टकोड कॉलम शामिल है। मैं पोस्टकोड से रिक्त स्थान को पट्टी करना चाहता हूं और किसी विशेष पैटर्न से मेल खाने वाला कोई भी चयन करना चाहता हूं। मैं एसक्यूएल सर्वर 2005 पर टी-एसक्यूएल में यह कोशिश कर रहा हूं (थोड़ा सा सरलीकृत):एक प्रतिस्थापन के साथ चुनें()

SELECT Replace(Postcode, ' ', '') AS P 
FROM Contacts 
WHERE P LIKE 'NW101%' 

लेकिन मुझे निम्न त्रुटि मिलती है;

Msg 207, Level 16, State 1, Line 3 
Invalid column name 'P'. 

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

+1

आप कर सकते थे एक materialized अनुक्रमित देखने के लिए, जहां REPLACE precomputed किया जाएगा और एक शारीरिक सूचकांक का हिस्सा है, और आपको लगता है कि मूल डेटा या टेबल बदले बिना बंद खोज सकते हैं पैदा करते हैं। –

उत्तर

32

अपने WHERE खंड में उपनाम (P) का उपयोग न करें।

आप WHERE खंड में फिर से वही REPLACE तर्क का उपयोग कर सकते:

SELECT Replace(Postcode, ' ', '') AS P 
FROM Contacts 
WHERE Replace(Postcode, ' ', '') LIKE 'NW101%' 

या निक के जवाब में वर्णित के रूप में एक aliased उप क्वेरी का उपयोग करें।

+0

यदि पोस्टकोड 'रिक्त स्थान से शुरू होता है तो यह काम नहीं करेगा। –

+0

यह ओपी की ज़रूरत नहीं करता है ... वह अन-स्पेस संस्करण पर 'LIKE' का उपयोग करने का प्रयास कर रहा है ... –

+0

धन्यवाद ओडेड! ये मेरे लिए सही है। –

11

आप संदर्भित कर सकते हैं यदि आप क्वेरी लपेट, इस तरह कि जिस तरह से है:

SELECT P 
FROM (SELECT Replace(Postcode, ' ', '') AS P 
     FROM Contacts) innertable 
WHERE P LIKE 'NW101%' 

, लिपटे एक उपनाम का चयन देना सुनिश्चित भी अप्रयुक्त रहो (SQL सर्वर एक IIRC के बिना यह अनुमति नहीं है)

2

आप एक उपनाम P बना रहे हैं और बाद में where खंड में आप इसका उपयोग कर रहे हैं, यही समस्या पैदा कर रही है। where में P का उपयोग न करें, तब इस प्रयास करें:

SELECT Replace(Postcode, ' ', '') AS P FROM Contacts 
WHERE Postcode LIKE 'NW101%' 
2

आप हर जगह अपनी अभिव्यक्ति को दोहराना आप इसका इस्तेमाल करना चाहते हैं:

SELECT Replace(Postcode, ' ', '') AS P 
FROM Contacts 
WHERE Replace(Postcode, ' ', '') LIKE 'NW101%' 

या आप इसे एक सबक्वेरी कर सकते हैं

select P 
from (
SELECT Replace(Postcode, ' ', '') AS P 
FROM Contacts 
) t 
WHERE P LIKE 'NW101%' 
2

Oded's answer पर विस्तार करने के लिए, आपके वैचारिक मॉडल को यहां थोड़ा समायोजन की आवश्यकता है। कॉलम नामों के एलिसिंग (ASSELECT सूची में खंड) SELECT की प्रसंस्करण में बहुत देर हो चुकी है, यही कारण है कि उपनाम WHERE खंडों के लिए उपलब्ध नहीं हैं। वास्तव में, केवल एक चीज है कि उसके बाद स्तंभ अलियासिंग छँटाई है होता है, यही कारण है कि (SELECT पर डॉक्स उद्धृत करने के लिए) जो:

column_alias खंड एक ORDER BY में इस्तेमाल किया जा सकता है। हालांकि, इसका उपयोग WHERE, GROUP BY, या HAVING खंड में नहीं किया जा सकता है।

आप SELECT सूची में एक जटिल अभिव्यक्ति है, तो आप इसके बारे में चिंतित हो सकता है जब यह SELECT सूची में दिखाई देता है और (माना) एक WHERE खंड 'दो बार मूल्यांकन किया जा रहा' - हालांकि, क्वेरी इंजन चालाक है क्या हो रहा है यह जानने के लिए पर्याप्त है।आप अभिव्यक्ति आपकी क्वेरी में दो बार दिखाया होने से बचाने के लिए चाहते हैं, तो आप की तरह

SELECT c1, c2, c3, expr1 
FROM 
    (SELECT c1, c2, c3, some_complicated_expression AS expr1) inner 
WHERE expr1 = condition 

जो some_complicated_expression से बचा जाता है शारीरिक रूप से दो बार प्रदर्शित कुछ कर सकते हैं।

+0

+1 स्पष्ट स्पष्टीकरण आकाश के लिए धन्यवाद। मुझे लगता है कि, संक्षेप में, मैं प्रतिस्थापन() को दोहराने से परहेज कर रहा था; और यह शायद मुझे सही समाधान देखने से रोक रहा था। धन्यवाद! –

+0

यह सही उत्तर होना चाहिए था। मूल रूप से, चयन से पहले कहां संसाधित किया जा रहा है। इसलिए, WHERE क्लॉज को पी के रूप में उपरोक्त कॉलम के मौजूदा से अवगत नहीं होगा, क्योंकि कॉलम पी एक गणना मूल्य है, क्योंकि सबक्वायरी दृष्टिकोण का उपयोग समाधान में से एक होगा दोबारा प्रतिस्थापन() दो बार करने की तुलना में । – frostshoxx

2
SELECT * 
FROM Contacts 
WHERE ContactId IN 
    (SELECT a.ContactID 
    FROM 
     (SELECT ContactId, Replace(Postcode, ' ', '') AS P 
     FROM Contacts 
     WHERE Postcode LIKE '%N%W%1%0%1%') a 
    WHERE a.P LIKE 'NW101%') 
3

अगर तुम कभी एक सूचकांक का उपयोग कर के किसी भी आशा चाहते हैं, एक सुसंगत तरीके से डेटा (हटाया रिक्तियों के साथ) की दुकान। या तो बस रिक्त स्थान हटाएं या एक स्थिर गणना वाले कॉलम को जोड़ें, फिर आप उस कॉलम से केवल चयन कर सकते हैं और जब भी आप अपनी क्वेरी चलाते हैं तो सभी जगहों को ओवरहेड हटाने की आवश्यकता नहीं होती है।

एक कायम गणना कॉलम जोड़ें:

ALTER TABLE Contacts ADD PostcodeSpaceFree AS Replace(Postcode, ' ', '') PERSISTED 
go 
CREATE NONCLUSTERED INDEX IX_Contacts_PostcodeSpaceFree 
ON Contacts (PostcodeSpaceFree) --INCLUDE (covered columns here!!) 
go 

सिर्फ रिक्त स्थानों को हटाकर स्तंभ ठीक करने के लिए उपयोग करें:

UPDATE Contacts 
    SET Postcode=Replace(Postcode, ' ', '') 

अब आप इस तरह से खोज सकते हैं, या तो का चयन एक सूचकांक का उपयोग कर सकते हैं:

--search the PERSISTED computed column 
SELECT 
    PostcodeSpaceFree 
    FROM Contacts 
    WHERE PostcodeSpaceFree LIKE 'NW101%' 

या

--search the fixed (spaces removed column) 
SELECT 
    Postcode 
    FROM Contacts 
    WHERE PostcodeLIKE 'NW101%' 
+0

इस महान व्याख्या को देने के लिए समय निकालने के लिए धन्यवाद, केएम। दुर्भाग्यवश प्रश्न में डेटाबेस 'विरासत' प्रणाली का हिस्सा है जिसे मुझे केवल पढ़ने के लिए ही व्यवहार करना है। लेकिन मैं अनुक्रमण के बारे में आपके बिंदु की सराहना करता हूं। मुझे लगातार गणना वाले कॉलम के बारे में पता नहीं था - इसलिए मैंने कुछ सीखा है। धन्यवाद! –

0

यह काम करेगा:

SELECT Replace(Postcode, ' ', '') AS P 
FROM Contacts 
WHERE Replace(Postcode, ' ', '') LIKE 'NW101%' 
संबंधित मुद्दे