2009-06-03 11 views
144

क्वेरी मैं चल रहा हूँ इस प्रकार है, फिर भी मैं यह त्रुटि हो रही है:का उपयोग स्तंभ उर्फ ​​

#1054 - Unknown column 'guaranteed_postcode' in 'IN/ALL/ANY subquery'

SELECT `users`.`first_name`, `users`.`last_name`, `users`.`email`, 
SUBSTRING(`locations`.`raw`,-6,4) AS `guaranteed_postcode` 
FROM `users` LEFT OUTER JOIN `locations` 
ON `users`.`id` = `locations`.`user_id` 
WHERE `guaranteed_postcode` NOT IN #this is where the fake col is being used 
(
SELECT `postcode` FROM `postcodes` WHERE `region` IN 
(
    'australia' 
) 
) 

मेरा प्रश्न है: मैं क्यों कर रहा हूँ एक ही डीबी क्वेरी के खंड में नकली कॉलम का उपयोग करने में असमर्थ?

उत्तर

334

आप केवल ग्रुप द्वारा आदेश देकर या होने खंड में स्तंभ कल्पित नामों का प्रयोग कर सकते हैं।

Standard SQL doesn't allow you to refer to a column alias in a WHERE clause. This restriction is imposed because when the WHERE code is executed, the column value may not yet be determined.

से MySQL documentation

कॉपी किया गया के रूप में टिप्पणी में कहा, बजाय होने काम कर सकते हैं का उपयोग कर। हालांकि इस WHERE vs HAVING पर पढ़ने के लिए सुनिश्चित करें।

+11

+1 रेफरी (और सटीकता) त्वरित और सटीक प्रतिक्रिया के लिए –

+1

चियर्स के लिए! मैंने हैविंग क्लॉज में एक नज़र डाली है और इस क्वेरी को सफलतापूर्वक चलाने के लिए एक तरीका तैयार किया है। फिर से धन्यवाद। – James

+26

यदि किसी और के पास मेरे जैसा ही प्रोब है, जहां क्लॉज असफल होने पर एलियाड कॉल का उपयोग कर रहा था - 'हैवरिंग' के लिए 'WHERE' को स्वैप करना, इसे ठीक से +1 अच्छा जवाब दें। – megaSteve4

22

विक्टर के रूप में बताया, समस्या उर्फ ​​के साथ है। यह हालांकि बचा जा सकता है, अभिव्यक्ति जहां एक्स में वाई खंड में सीधे डाल कर:

SELECT `users`.`first_name`,`users`.`last_name`,`users`.`email`,SUBSTRING(`locations`.`raw`,-6,4) AS `guaranteed_postcode` 
FROM `users` LEFT OUTER JOIN `locations` 
ON `users`.`id` = `locations`.`user_id` 
WHERE SUBSTRING(`locations`.`raw`,-6,4) NOT IN #this is where the fake col is being used 
(
SELECT `postcode` FROM `postcodes` WHERE `region` IN 
(
    'australia' 
) 
) 

हालांकि, मुझे लगता है कि यह बहुत ही अक्षम है, के बाद से सबक्वेरी बाहरी क्वेरी के हर पंक्ति के लिए क्रियान्वित किया जाना है।

+1

@ ड्रोडियन, हाँ मुझे विश्वास है कि यह ** गंभीर ** धीमा और अक्षम है। – Pacerier

17

मानक SQL (या MySQL) एक कहां खंड में स्तंभ उपनाम के उपयोग की अनुमति नहीं है क्योंकि

when the WHERE clause is evaluated, the column value may not yet have been determined.

(MySQL documentation से)। आप क्या कर सकते हैं में कॉलम मान की गणना करें खंड, मान को एक चर में सहेजें, और फ़ील्ड सूची में इसका उपयोग करें। उदाहरण के लिए आप ऐसा कर सकता है:

SELECT `users`.`first_name`, `users`.`last_name`, `users`.`email`, 
@postcode AS `guaranteed_postcode` 
FROM `users` LEFT OUTER JOIN `locations` 
ON `users`.`id` = `locations`.`user_id` 
WHERE (@postcode := SUBSTRING(`locations`.`raw`,-6,4)) NOT IN 
(
SELECT `postcode` FROM `postcodes` WHERE `region` IN 
(
    'australia' 
) 
) 

इस अभिव्यक्ति को दोहरा जब यह जटिल होती है, कोड आसान बनाए रखने के लिए कर रही है टाल।

+5

यह प्रलेखन के साथ यह संघर्ष नहीं करता है [जो कहता है] (http://stackoverflow.com/questions/16715504/mysql-define-a-variable-within-select-and-use-it-within-the-same- चयन करें/16715618 # 16715618) * "एक सामान्य नियम के रूप में, आपको किसी उपयोगकर्ता चर के लिए कोई मान निर्दिष्ट नहीं करना चाहिए और उसी कथन के भीतर मान को पढ़ना नहीं चाहिए। आपको परिणाम मिलने वाले परिणाम मिल सकते हैं, लेकिन इसकी गारंटी नहीं है।" *? – Arjan

+0

यह निश्चित रूप से ध्यान में रखना कुछ है। यह हमेशा मेरे लिए काम करता है, मुझे लगता है कि एक बयान के विभिन्न हिस्सों के मूल्यांकन के आदेश को तय करना था (पहले कहां, फिर चुनें, फिर ग्रुप बाय, ...) लेकिन मेरे पास इसका कोई संदर्भ नहीं है – Joni

+0

कुछ उदाहरण: कुछ [दावा] (http://stackoverflow.com/questions/16715504/mysql-define-a-variable-within-select-and-use-it-within-the-same-select/24551337# 24551337) कि उनके लिए 'चयन करें @code: = sum (2), 2 * @ code' MySQL 5.5 में काम करता है, लेकिन मेरे लिए 5.6 में दूसरा कॉलम पहले आमंत्रण पर NULL उत्पन्न करता है, और पिछले परिणाम * 2 बार * देता है दोबारा दौडो। काफी दिलचस्प है, दोनों '@code: = 2, 2 * @ code' चुनें और' चुनें @code: = rand(), 2 * @ code' मेरे 5.6 (आज) में काम करता प्रतीत होता है। लेकिन वे वास्तव में चयन खंड में लिख रहे हैं और पढ़ रहे हैं; आपके मामले में आप इसे कहां सेट कर रहे हैं। – Arjan

1

मैं mysql 5.5.24 का उपयोग कर रहा है और निम्नलिखित कोड काम करता है:

select * from (
SELECT `users`.`first_name`, `users`.`last_name`, `users`.`email`, 
SUBSTRING(`locations`.`raw`,-6,4) AS `guaranteed_postcode` 
FROM `users` LEFT OUTER JOIN `locations` 
ON `users`.`id` = `locations`.`user_id` 
) as a 
WHERE guaranteed_postcode NOT IN --this is where the fake col is being used 
(
SELECT `postcode` FROM `postcodes` WHERE `region` IN 
(
    'australia' 
) 
) 
10

हो सकता है कि मेरा उत्तर बहुत देर हो चुकी है, लेकिन यह दूसरों की मदद कर सकते हैं।

आप किसी अन्य का चयन करें बयान के साथ यह लगा और इसे करने के लिए जहां खंड का उपयोग कर सकते हैं।

SELECT * FROM (Select col1, col2,...) as t WHERE t.calcAlias > 0 

calcAlias ​​उर्फ ​​स्तंभ गणना किया गया है।

+0

अच्छा और छोटा उपयोग नहीं किया है, लेकिन यह उपयोगी होने के लिए बहुत अस्पष्ट है। – Agamemnus

+0

@Agamemnus, इसका मतलब क्या है? – Pacerier

+0

सवाल यह था, "मैं उसी डीबी क्वेरी के खंड में फर्जी कॉलम का उपयोग करने में असमर्थ क्यों हूं?" यह उत्तर उस प्रश्न का उत्तर नहीं देता है और एक क्रिया गायब है। – Agamemnus

7

आपके द्वारा चुने गए क्षेत्रों में गणना की फिल्टर के लिए HAVING क्लॉज़ का उपयोग करें और उपनाम

+0

का उपयोग करें, मैंने अभी आपके बाद 1 साल अमेरिका पाया। क्रेडिट आप से संबंधित है: डी –

+0

@ fahimg23 - सुनिश्चित नहीं है। मैंने एक कारण खोजने की कोशिश की, लेकिन मैं नहीं कर सकता! हालांकि, 'कहां' और 'हैविंग' के बीच मतभेदों को ध्यान में रखें। वे समान नहीं हैं। https://stackoverflow.com/search?q=where+vs+having – rinogo

+0

अद्यतन: ऐसा इसलिए है क्योंकि [यह उत्तर] (https://stackoverflow.com/a/942592/114558) एक ही समाधान प्रदान करता है लेकिन अधिक जानकारी के साथ। – rinogo

0

मानक SQL एक कहां खंड में स्तंभ नामों पर संदर्भ की अनुमति नहीं देता कर सकते हैं। यह प्रतिबंध लगाया गया है क्योंकि जब WHERE क्लॉज का मूल्यांकन किया जाता है, तो स्तंभ मान अभी तक निर्धारित नहीं किया जा सकता है। उदाहरण के लिए, निम्न क्वेरी अवैध है:

चयन आईडी, COUNT (*) tbl_name से cnt जहां cnt> 0 ग्रुप आईडी के आधार पर;

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