मैंने इस तरह की कई पोस्ट देखी हैं, लेकिन मैं जिस परिदृश्य के साथ काम कर रहा हूं, उसके लिए कोई भी उपयुक्त नहीं है। पिछले 12 में प्रत्येक महीने के लिए एक डीबी और कुल परिणामों को क्वेरी करने का प्रयास कर रहा है। यदि किसी विशेष महीने के लिए कोई परिणाम मौजूद नहीं है, तो मुझे उस विशेष महीने के लिए एक पंक्ति में 0 चाहिए।

इस क्वेरी को चलाने से नवंबर 2016-मार्च 2017 के लिए डेटा प्राप्त होता है, जिसके पहले/बाद में कोई परिणाम नहीं होता है:

SELECT SUM(PRICE) SumPrice, COUNT(*) TotalNum, EXTRACT(MONTH FROM SALE_DATE) Mo, EXTRACT(YEAR FROM SALE_DATE) Yr
FROM SALES_HIST
WHERE SALE_DATE BETWEEN TRUNC(ADD_MONTHS((LAST_DAY(SYSDATE)+1),-12)) 
AND LAST_DAY(SYSDATE)
AND ITEMNO = 'ABCD'
GROUP BY EXTRACT(MONTH FROM SALE_DATE), EXTRACT(YEAR FROM SALE_DATE)
ORDER BY Yr, Mo;

कुछ खोज के बाद, मैं फ्लाई पर पिछले 12 महीनों की सूची तैयार करने के लिए इस प्रश्न के साथ आया:

SELECT
EXTRACT(MONTH FROM 
ADD_MONTHS(TRUNC(ADD_MONTHS((LAST_DAY(SYSDATE)+1),-12)), LEVEL - 1)) calMo,
EXTRACT(YEAR FROM 
ADD_MONTHS(TRUNC(ADD_MONTHS((LAST_DAY(SYSDATE)+1),-12)), LEVEL - 1)) calYr
FROM DUAL
CONNECT BY LEVEL <= 12;

जो मेरा मानना ​​​​है कि डेटा अंतराल को भरने के लिए मुझे अपनी क्वेरी के भीतर अस्थायी तालिका के रूप में उपयोग करने में सक्षम होना चाहिए। यही वह है जिसके साथ मैं छेड़छाड़ कर रहा हूं:

WITH cal AS (
SELECT
  EXTRACT(MONTH FROM ADD_MONTHS(TRUNC(ADD_MONTHS((LAST_DAY(SYSDATE)+1),-12)), LEVEL - 1)) calMo,
  EXTRACT(YEAR FROM ADD_MONTHS(TRUNC(ADD_MONTHS((LAST_DAY(SYSDATE)+1),-12)), LEVEL - 1)) calYr
FROM DUAL
CONNECT BY LEVEL <= 12
)
select cal.calMo, cal.calYr, NVL(count(*), 0)
from cal
left join SALES_HIST sh on cal.calMo = EXTRACT(MONTH FROM sh.SALE_DATE)
WHERE SALE_DATE BETWEEN TRUNC(ADD_MONTHS((LAST_DAY(SYSDATE)+1),-12)) AND LAST_DAY(SYSDATE)
AND ITEMNO = 'ABCD'
group by cal.calMo, cal.calYr
order by cal.calYr, cal.calMo;

लेकिन ऐसा लगता है कि प्रारंभिक क्वेरी के समान परिणाम वापस आ गए हैं। मुझे लगता है कि मुझे शामिल होने के साथ कुछ याद आ रहा है, लेकिन बिल्कुल निश्चित नहीं है। किसी भी तरह की सहायता का स्वागत किया जाएगा। धन्यवाद!

1
Dan 19 सितंबर 2017, 00:31
क्या आप SALES_HIST तालिका का डेटा और अंतिम SQL का परिणाम कृपया पोस्ट कर सकते हैं?
 – 
Ted at ORCL.Pro
19 सितंबर 2017, 00:44

1 उत्तर

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

जब आप WHERE क्लॉज का उपयोग करते हैं तो यह LEFT JOIN की सभी परिणामी पंक्तियों को फ़िल्टर करता है जो WHERE क्लॉज की स्थिति से पूरी नहीं होती हैं, इस प्रकार सभी NULL मान हटा दिए जाएंगे। यदि आप अपनी sales_hist तालिका पर AND शर्त के भीतर उपयोग करते हैं, तो यह NULL मान बनाने से पहले उन रिकॉर्ड्स को फ़िल्टर करेगा जो cal तालिका में महीनों/वर्षों से मेल नहीं खाते। इसके अलावा, * के बजाय गिनती पर sh.itemno का उपयोग करें क्योंकि यह cal तालिका में प्रत्येक प्रविष्टि की गणना करेगा जिसमें प्रत्येक महीने में 1 होगा।

SELECT cal.calmo, 
       cal.calyr, 
       NVL(COUNT(sh.itemno), 0) /*changed from * to sh.itemno*/
  FROM cal
  LEFT JOIN sales_hist sh 
    ON cal.calMo = EXTRACT(MONTH FROM sh.sale_date)
   AND sale_date BETWEEN TRUNC(ADD_MONTHS((LAST_DAY(SYSDATE)+1),-12))
                     AND LAST_DAY(SYSDATE) /*changed from WHERE to AND*/
   AND itemno = 'ABCD'
 GROUP BY cal.calmo, 
          cal.calyr
 ORDER BY cal.calyr, 
          cal.calmo;

नमूना डेटा

CREATE TABLE sales_hist AS
SELECT TO_DATE('09172017','MMDDYYYY') sale_date,
       'ABCD' itemno
  FROM dual
 UNION ALL
SELECT TO_DATE('10172016','MMDDYYYY') sale_date,
       'ABCD' itemno
  FROM dual
 UNION ALL
SELECT TO_DATE('10182016','MMDDYYYY') sale_date,
       'ABCD' itemno
  FROM dual
   UNION ALL
SELECT TO_DATE('09172016','MMDDYYYY') sale_date,
       'ABCD' itemno
  FROM dual
 ;

नमूना परिणाम। ध्यान दें कि 09172016 गिनती में शामिल नहीं है।

CALMO   CALYR   NVL(COUNT(SH.ITEMNO),0)
10      2016    2
11      2016    0
12      2016    0
1       2017    0
2       2017    0
3       2017    0
4       2017    0
5       2017    0
6       2017    0
7       2017    0
8       2017    0
9       2017    1
0
Ferdinand Gaspar 19 सितंबर 2017, 03:21
1
बहुत बहुत धन्यवाद! यह पूरी तरह से काम किया। मैंने इसे राइट जॉइन का उपयोग करने के लिए फिर से काम किया जिससे मुझे चीजों को थोड़ा बेहतर समझने में मदद मिली। मुझे नहीं पता था कि इस तरह की नकारात्मक चीजें कहां हैं, या कि आप शामिल होने के दौरान केवल और बिना WHERE का उपयोग कर सकते हैं।
 – 
Dan
21 सितंबर 2017, 17:39