WHERE क्लॉज में एक कॉलम एलियास का जिक्र


166
SELECT logcount, logUserID, maxlogtm
   , DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
WHERE daysdiff > 120

मुझे मिला

"अमान्य कॉलम नाम दिनोंदिफ"।

Maxlogtm एक डेटाइम फ़ील्ड है। यह थोड़ा सामान है जो मुझे पागल कर देता है।


mysql के लिए निश्चित नहीं है, लेकिन शायद उर्फ ​​को टिक्स में लपेटने की आवश्यकता है `daysdiff`
ऐश बर्लज़ेंको 19

जवाबों:


194
SELECT
   logcount, logUserID, maxlogtm,
   DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
WHERE ( DATEDIFF(day, maxlogtm, GETDATE() > 120)

आम तौर पर आप WHEREखंड में क्षेत्र उपनामों का उल्लेख नहीं कर सकते । (इसे SELECTउपनाम सहित संपूर्ण के रूप में सोचो , के बाद लागू किया जाता हैWHERE क्लॉज के ।)

लेकिन, जैसा कि अन्य उत्तरों में बताया गया है, आप SQL को क्लॉज़ SELECTसे पहले संभाला जाने के लिए बाध्य कर सकते हैं WHERE। यह आमतौर पर कोष्ठक के साथ ऑपरेशन के तार्किक क्रम को लागू करने के लिए या एक सामान्य तालिका अभिव्यक्ति (CTE) के साथ किया जाता है:

कोष्ठक / सबसिलेक्ट:

SELECT
   *
FROM
(
   SELECT
      logcount, logUserID, maxlogtm,
      DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
   FROM statslogsummary   
) as innerTable
WHERE daysdiff > 120

या उसी के सीटीई संस्करण के लिए एडम का जवाब देखें।


16
यह सीधे संभव नहीं है, क्योंकि कालानुक्रमिक रूप से, जहां SELECT से पहले होता है, जो हमेशा निष्पादन श्रृंखला का अंतिम चरण होता है। REFER - stackoverflow.com/questions/356675/…
david blaine

afaik अगर चयन में उपनाम एक सहसंबद्ध सबक्वेरी है तो यह काम करेगा जबकि CTE समाधान नहीं करेगा।
रेज़वान फ्लावियस पांडा

जैसा कि पास्कल ने अपने उत्तर में यहां उल्लेख किया है कि stackoverflow.com/a/38822328/282887 , आप HAVING क्लॉज का उपयोग कर सकते हैं जो उपश्रेणियों की तुलना में तेजी से काम करता है।
बख्तियार

@ बख्तियार यह HAVINGसवाल एमएस-एसक्यूएल सहित अधिकांश एसक्यूएल वातावरण में काम नहीं करता है, जिसके बारे में यह सवाल है। (टी-एसक्यूएल में, HAVINGएक समग्र फ़ंक्शन की आवश्यकता होती है।)
जेमी एफ

72

यदि आप अपने WHEREउपवाक्य में उपनाम का उपयोग करना चाहते हैं , तो आपको इसे उप-चयन या सीटीई में लपेटने की आवश्यकता है :

WITH LogDateDiff AS
(
   SELECT logcount, logUserID, maxlogtm
      , DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
   FROM statslogsummary
)
SELECT logCount, logUserId, maxlogtm, daysdiff
FROM LogDateDiff
WHERE daysdiff > 120

2
क्या आपको पता है कि यह मेला दक्षता बुद्धिमान कैसे होता है? क्या CTE का उपयोग करने से अतिरिक्त ओवरहेड होता है?
जेम्स

5
एक CTE एक उप-क्वेरी के लिए सिर्फ प्रीटियर सिंटैक्स है, इसलिए प्रदर्शन उसी के समान होगा। मेरे अनुभव में, प्रदर्शन अंतर कुछ ऐसा नहीं है, जिसने मुझे इस तरह के संचालन के लिए चिंतित किया है, लेकिन यह आपके वातावरण में यह देखने के लिए परीक्षण करने के लिए काफी सरल होना चाहिए कि क्या आपकी विशिष्ट तालिका / क्वेरी इस बनाम के साथ प्रतिकूल रूप से प्रभावित होती है? सूत्र विशेष रूप से जहां खंड में। मुझे संदेह है कि आपको कोई फर्क नहीं पड़ेगा।
एडम वेंगर

CTEs तब तक सुपर अच्छे हैं जब तक आप एक सबक्वेरी के रूप में उपयोग करने की कोशिश नहीं करते। मुझे उन्हें घोंसला बनाने के लिए विचारों के रूप में बनाने का सहारा लेना पड़ा है। मैं इसे एक गंभीर एसक्यूएल की कमी
सहानुभूति

10

अपने कोड को दोहराए बिना इसे करने का सबसे प्रभावी तरीका WHERE के बजाय HAVING का उपयोग है

SELECT logcount, logUserID, maxlogtm
   , DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary
HAVING daysdiff > 120

1
मुझे लगता है कि HAVINGउपनाम का उपयोग मानक नहीं है (यह MySQL पर काम करता है, हालांकि)। विशेष रूप से, मुझे लगता है कि यह SQL सर्वर के साथ काम नहीं करता है।
टोकलैंड

2
एसक्यूएल सर्वर:[S0001][207] Invalid column name 'daysdiff'
वादज़्मी

3
एसक्यूएल सर्वर:[S0001][8121] Column 'day' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.
वादज़्मी

9

यदि आप CTE में अपने सभी कॉलमों को सूचीबद्ध नहीं करना चाहते हैं, तो इसका उपयोग करने का एक और तरीका होगा outer apply:

select
    s.logcount, s.logUserID, s.maxlogtm,
    a.daysdiff
from statslogsummary as s
    outer apply (select datediff(day, s.maxlogtm, getdate()) as daysdiff) as a
where a.daysdiff > 120

6

कैसे एक उपश्रेणी का उपयोग करने के बारे में (यह मेरे लिए मैसकल में काम किया)?

SELECT * from (SELECT logcount, logUserID, maxlogtm
   , DATEDIFF(day, maxlogtm, GETDATE()) AS daysdiff
FROM statslogsummary) as 'your_alias'
WHERE daysdiff > 120

4

प्रलेखन के अनुसार MySQL में काम करना:

होने खंड एसक्यूएल को जोड़ा गया है, क्योंकि जहां कीवर्ड कुल कार्यों के साथ प्रयोग नहीं किया जा सकता है।


4

आप स्तंभ उपनाम का उल्लेख कर सकते हैं, लेकिन आपको इसका उपयोग करने की आवश्यकता है CROSS/OUTER APPLY:

SELECT s.logcount, s.logUserID, s.maxlogtm, c.daysdiff
FROM statslogsummary s
CROSS APPLY (SELECT DATEDIFF(day, s.maxlogtm, GETDATE()) AS daysdiff) c
WHERE c.daysdiff > 120;

DBFiddle डेमो

पेशेवरों:

  • अभिव्यक्ति की एकल परिभाषा (नकल-पेस्ट की आवश्यकता को बनाए रखना / आसान करना)
  • CTE / आउटरक्वारी के साथ पूरी क्वेरी लपेटने की कोई आवश्यकता नहीं है
  • में संदर्भित करने की संभावना WHERE/GROUP BY/ORDER BY
  • संभव बेहतर प्रदर्शन (एकल निष्पादन)

1
इसके लायक है कि यह केवल SQL सर्वर में काम करता है
मार्टिन Zinovsky

1
@MartinZinovsky प्रश्न को टैग किया गया है sql-serverऔर t-sql:)
लुकाज़ स्ज़ोज़ा

0

यहाँ आया है कि करने के लिए कुछ इसी तरह की तलाश में है, लेकिन एक मामले के साथ कब, और कहां इस तरह का उपयोग कर समाप्त: WHERE (CASE WHEN COLUMN1=COLUMN2 THEN '1' ELSE '0' END) = 0हो सकता है आप इस्तेमाल कर सकते हैं DATEDIFFमें WHEREसीधे। कुछ इस तरह:

SELECT logcount, logUserID, maxlogtm
FROM statslogsummary
WHERE (DATEDIFF(day, maxlogtm, GETDATE())) > 120
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.