अज्ञात कॉलम जहां क्लॉज में


126

मेरे पास एक सरल प्रश्न है:

SELECT u_name AS user_name FROM users WHERE user_name = "john";

मुझे मिलता है Unknown Column 'user_name' in where clause। क्या मैं 'user_name'बयान के अन्य भागों में भी उल्लेख नहीं कर सकता हूं select 'u_name as user_name'?

जवाबों:


94

एसक्यूएल का मूल्यांकन पीछे से, दाएं से बाएं किया जाता है। इसलिए जहां क्लॉज को पार्स किया गया है और चयन क्लॉज से पहले मूल्यांकन करें। इसके कारण user_name के लिए u_name का परिवर्तन अभी तक नहीं हुआ है।


30
"बैकवर्ड" के बजाय मुझे लगता है कि "अंदर बाहर" कहने के लिए यह अधिक समझ में आता है
जो फिलिप्स

4
यह कहने के लिए और अधिक समझ में आता है कि पूरे बयान को एक जटिल, मल्टीस्टेज प्रक्रिया में पार्स, रूपांतरित और अनुकूलित किया गया है। "एसक्यूएल का मूल्यांकन पीछे से किया जाता है, दाएं से बाएं" बस गलत है
डेविड एल्ड्रिज

3
अपूर्ण उत्तर के रूप में उपयोगकर्ता ने पूछा कि क्या 'user_name' बयान में इस्तेमाल किया जा सकता है, जो इसके बाद हो सकता है जैसे '
HAVING

45

व्हाट अबाउट:

SELECT u_name AS user_name FROM users HAVING user_name = "john";

16
क्यों आप का प्रयोग करेंगे HAVINGके बजाय WHEREइस मामले में?
पेटीगो

4
@PeteGO पॉल डिक्सन के जवाब को देखें। tldr; HAVING का मूल्यांकन बाद में WHERE की तुलना में और अधिक महत्वपूर्ण रूप से SELECT किया गया है।
९'१

38

निम्नलिखित MySQL मैनुअल पेज देखें: http://dev.mysql.com/doc/refman/5.0/en/select.html

"एक select_expr को AS alias_name का उपयोग करके एक उपनाम दिया जा सकता है। उपनाम का उपयोग अभिव्यक्ति के कॉलम नाम के रूप में किया जाता है और इसका उपयोग GROUP BY, ORDER BY, या HAVING क्लॉस में किया जा सकता है।"

(...)

WHERE क्‍लॉज में कॉलम उर्फ ​​का उल्‍लेख करना अनुज्ञेय नहीं है, क्‍योंकि WHERE क्‍लॉज निष्पादित होने पर कॉलम मान अभी तक निर्धारित नहीं किया जा सकता है। खंड B.5.4.4, "स्तंभ उपनाम के साथ समस्याएं" देखें।


इसके अलावा, (MySQL के आदमी से) ध्यान दें: SQL मानक की आवश्यकता है कि HAVING को ग्रुप बीओ क्लॉज या कुल कार्यों में उपयोग किए जाने वाले कॉलम में केवल कॉलम का संदर्भ देना चाहिए। हालाँकि, MySQL इस व्यवहार के लिए एक एक्सटेंशन का समर्थन करता है, और HAVING को सेलेक्ट सूची में कॉलम और बाहरी सबक्वेरीज़ में कॉलम के रूप में अच्छी तरह से संदर्भित करने की अनुमति देता है।
विंसेंट पैज़ेलर सेप

12
select u_name as user_name from users where u_name = "john";

इसे इस तरह से सोचें, आपका वह खंड जहां पहले मूल्यांकन करता है, यह निर्धारित करने के लिए कि किन पंक्तियों (या सम्मिलित पंक्तियों) को वापस करने की आवश्यकता है। एक बार जहाँ क्लॉज़ निष्पादित हो जाता है, उसके लिए सेलेक्ट क्लॉज़ चलता है।

इसे बेहतर तरीके से रखने के लिए, इसकी कल्पना करें:

select distinct(u_name) as user_name from users where u_name = "john";

आप दूसरे के बिना पहली छमाही का संदर्भ नहीं दे सकते। जहां हमेशा पहले मूल्यांकन किया जाता है, उसके बाद चयन खंड।


11

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

SELECT nodes.*, (SELECT (COUNT(*) FROM attachments 
WHERE attachments.nodeid = nodes.id) AS attachmentcount 
FROM nodes
WHERE attachmentcount > 0;

आपको "अज्ञात कॉलम 'अटैचमेंट' WHERE क्लॉज में एक त्रुटि मिलेगी।"

समाधान वास्तव में काफी सरल है - बस उपनाम को उस बयान से बदलें जो उपनाम का उत्पादन करता है, जैसे:

SELECT nodes.*, (SELECT (COUNT(*) FROM attachments 
WHERE attachments.nodeid = nodes.id) AS attachmentcount 
FROM nodes 
WHERE (SELECT (COUNT(*) FROM attachments WHERE attachments.nodeid = nodes.id) > 0;

आपको अभी भी उपनाम वापस मिल जाएगा, लेकिन अब एसक्यूएल को अज्ञात उपनाम में नहीं देना चाहिए।


1
मैं इस सटीक समस्या का सामना कर रहा था, और आपके उत्तर में आया - धन्यवाद! बस ध्यान दें, यह (समझ में आता है) बड़े डेटाबेस पर थोड़ा धीमा है, लेकिन मैं वैसे भी एक बेवकूफ विरासत में मिला डेटाबेस सेटअप के साथ काम कर रहा हूं।
लियाम न्यूमरच

मेरा मानना ​​है कि (आपकी क्वेरी में आपके पास एक अतिरिक्त है (COUNT(*)जो कहीं भी बंद नहीं है।
tftd 16

3
लेकिन क्या SELECT स्टेटमेंट दो बार नहीं चलाया गया है?
मतज

मैं अब तक कोई mysql विशेषज्ञ नहीं हूँ, लेकिन यह बहुत inperformat लगता है। मैंने अनुभव किया है कि नेस्टेड चयन क्वेरी को बहुत धीमा बनाते हैं।
GDY

8

आपके परिभाषित खंड का aliasस्वागत नहीं किया जाता है इसके लिए WHEREआपको खंड का उपयोग करना HAVINGहोगा

SELECT u_name AS user_name FROM users HAVING user_name = "john";

या आप सीधे मूल कॉलम नाम का उपयोग कर सकते हैं WHERE

SELECT u_name AS user_name FROM users WHERE u_name = "john";

जैसे ही आपके पास उपयोक्ता या किसी भी गणना के परिणामस्वरूप उपयोक्ता के रूप में परिभाषित उपयोगकर्ता का परिणाम होता है, इसे HAVINGखंड द्वारा एक्सेस किया जाएगा ।WHERE

SELECT u_name AS user_name ,
(SELECT last_name FROM users2 WHERE id=users.id) as user_last_name
FROM users  WHERE u_name = "john" HAVING user_last_name ='smith'

7

कोई एक:

SELECT u_name AS user_name
FROM   users
WHERE  u_name = "john";

या:

SELECT user_name
from
(
SELECT u_name AS user_name
FROM   users
)
WHERE  u_name = "john";

यदि आरडीबीएमएस इन-लाइन दृश्य में धक्का देने का समर्थन करता है तो बाद वाले को पूर्व जैसा ही होना चाहिए।



5

नहीं, आपको इसे सही नाम के साथ चुनने की आवश्यकता है। यदि आप किसी अन्य नाम से चयनित तालिका देते हैं तो आप उसका उपयोग कर सकते हैं।



1

WHEREखंड 1 और 2 के कारण खंड में अज्ञात कॉलम और लाइन 3 द्वारा हल किया गया:

  1. $sql = "SELECT * FROM users WHERE username =".$userName;
  2. $sql = "SELECT * FROM users WHERE username =".$userName."";
  3. $sql = "SELECT * FROM users WHERE username ='".$userName."'";

आपने क्या बदला है और क्यों? इसके अतिरिक्त, आपने कोड क्यों पोस्ट किया जो SQL इंजेक्शन के लिए व्यापक रूप से खुला है?
निको हसे

1

हो सकता है यह मदद करे।

आप ऐसा कर सकते हैं

SET @somevar := '';
SELECT @somevar AS user_name FROM users WHERE (@somevar := `u_name`) = "john";

यह काम करता हैं।

लेकिन आप क्या करते हैं सुनिश्चित करें!

  • यहाँ अनुक्रमित का उपयोग नहीं किया गया है
  • पूर्ण तालिका स्कैन की जाएगी - आपने लिमिट 1 भाग निर्दिष्ट नहीं किया है
  • तो, - यह बहुत बड़ी तालिकाओं पर SLLLOOOOOW होगा।

लेकिन, हो सकता है कि यह कुछ मामलों में मदद करे


0

जब आप अपनी क्वेरी के भीतर अपनी सारणी को अन्य नाम दे सकते हैं (जैसे, "उपयोगकर्ताओं से u.username का चयन करें!"), आपको उन स्तंभों के वास्तविक नामों का उपयोग करना होगा जिन्हें आप संदर्भित कर रहे हैं। एएस ही प्रभावित करता है कि खेतों को कैसे लौटाया जाता है।


मुझे लगता है कि आप उदाहरण के लिए MySql जैसे कुछ RDBMS में उपनाम का उपयोग कर सकते हैं। हालांकि आप Sql सर्वर के लिए सही हैं।
पेटीगो


0

बस यह समस्या थी।

सुनिश्चित करें कि डेटाबेस में इकाई के नाम पर कोई स्थान नहीं है।

उदाहरण के लिए 'user_name' के बजाय 'user_name'


-1

अपने कार्य को IN या OR शर्त का उपयोग करके देखें और यह क्वेरी स्पार्क-1.6.x पर काम कर रही है

 SELECT  patient, patient_id FROM `patient` WHERE patient IN ('User4', 'User3');

या

SELECT  patient, patient_id FROM `patient` WHERE patient = 'User1' OR patient = 'User2';

-1

मेरे लिए समस्या की जड़ एक संख्या थी जिसे मैंने WHERE क्लॉज में उपयोग करने के लिए कॉपी किया था। संख्या में कम से कम MySQL कार्यक्षेत्र के लिए "अदृश्य" प्रतीक था। मैंने क्रोम कंसोल में नंबर रखा था यह स्पष्ट रूप से दिखाई दे रहा था।


-2

मुझे भी यही समस्या थी, मुझे यह उपयोगी लगा।

mysql_query("SELECT * FROM `users` WHERE `user_name`='$user'");

$ 'यूजर को सिंगल कोट्स में रखना याद रखें।


1
यह कोड SQL इंजेक्शन के लिए व्यापक रूप से खुला है। दी गई समस्या को हल करने के लिए किसी को भी इस कोड का उपयोग नहीं करना चाहिए
निको हसे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.