मैं उन ग्राहकों को कैसे ढूंढ सकता हूं जिन्होंने पिछले 6 महीने में सबक्वायरी का उपयोग किए बिना कोई किताब नहीं खरीदी।

SELECT first_name, last_name, email
FROM customers
WHERE id NOT IN (
    SELECT customers.id
    FROM customers
    LEFT JOIN orders ON orders.customer_id = customers.id
    WHERE DATEDIFF(MONTH, orders.purchased_date, GETDATE()) < 6
    GROUP BY customers.id
);
0
eabasquliyev 8 जुलाई 2021, 02:05

3 जवाब

सबसे बढ़िया उत्तर

यहां उप-क्वेरी के बिना एक विकल्प है (स्पष्ट क्यों नहीं) ... बस क्रूर बल :)

Select C.first_name
      ,C.last_name
      ,C.email
      ,LastPurchase = max(O.purchased_date)
  From customers C
  Join orders    O on O.customer_id = C.customer_id 
  Group by C.customer_id
          ,C.first_name
          ,C.last_name
          ,C.email
  Having max(O.purchased_date) <= dateadd(month,-6,getdate())
2
John Cappelletti 7 जुलाई 2021, 23:49

EXCEPT एक kludge-y विकल्प के रूप में दिमाग में आता है। एक सीटीई सभी ग्राहक आईडी प्राप्त करता है और फिर ऑर्डर के आधार पर उन्हें हटा देता है जहां खरीद की तारीख 6 महीने के भीतर होती है। फिर आप ग्राहक तालिका में वापस सीटीई में शामिल हों।

with cte as (
   select customer_id from dbo.customers
   except
   select customer_id from dbo.orders where purchase_date >= dateadd(month, -6, getdate())
)
select cust.customer_id, ... 
from dbo.customers as cust
inner join cte on cte.customer_id = cust.customer_id
order by ...;
2
SMor 7 जुलाई 2021, 23:44

उप-क्वेरी का उपयोग क्यों नहीं करें? यह यहां नौकरी के लिए सबसे अच्छा उपकरण है। आप IN के बजाय NOT EXISTS के साथ अपनी क्वेरी (अभी भी एक उप-क्वेरी का उपयोग करते हुए) में सुधार कर सकते हैं और DATEDIFF फ़ंक्शन को सीधे अपने कॉलम पर लागू नहीं कर सकते हैं, क्योंकि यह क्वेरी को असंगत बनाता है ( यानी अनुक्रमणिका का उपयोग नहीं कर सकता)। साथ ही DATEDIFF तब और अब के बीच महीने के बदलावों को गिनता है, वास्तविक महीनों को नहीं। नीचे तर्क परिवर्तन देखें।

SELECT c.first_name, c.last_name, c.email
FROM customers c
WHERE NOT EXISTS (
    SELECT 1
    FROM orders o
    WHERE o.customer_id = c.customers.id
    AND o.purchased_date >= DATEADD(MONTH, -6, GETDATE())
)

तालिका उपनामों की भी हमेशा अनुशंसा की जाती है।

यह मानते हुए कि आपने प्रदर्शन के दृष्टिकोण से यह प्रश्न पूछा है, मैंने 499,290 क्लाइंट और 1,333,326 ऑर्डर के साथ वास्तविक तालिकाओं के विरुद्ध अनुमानित निष्पादन योजना का उपयोग करके इसके प्रदर्शन की मोटे तौर पर जाँच की। आपकी क्वेरी में ४३%, जॉन की क्वेरी ने ३९% (एक छोटा सुधार) लिया, मेरी क्वेरी ने ९% (एक बड़ा सुधार) लिया और एसमोर की क्वेरी ने ९% (फिर से एक बड़ा सुधार) लिया। इसलिए यदि प्रदर्शन वास्तव में आपके प्रश्न के बारे में है तो आपको यह पूछना चाहिए और कृत्रिम रूप से सर्वोत्तम प्रदर्शन करने वाले समाधान को बाधित नहीं करना चाहिए।

2
Dale K 13 जुलाई 2021, 09:59