आपको परिणामों को समतल करना होगा सही गणना प्राप्त करने के लिए, आपकी क्वेरी का।
आपने कहा था कि आपकी फाइल टेबल से दूसरी टेबल से एक-से-अनेक संबंध हैं
यदि SQL में केवल एक कीवर्ड है LOOKUP
JOIN
. में सब कुछ समेटने के बजाय कीवर्ड, यह अनुमान लगाना आसान होगा कि क्या तालिका A और तालिका B के बीच का संबंध JOIN
का उपयोग करके एक-से-एक है स्वचालित रूप से एक-से-कई का अर्थ होगा। मैंने खुद को पीछे कर लिया। वैसे भी, मुझे पहले से ही यह अनुमान लगाना चाहिए था कि आपकी फ़ाइलें dm_data के विरुद्ध एक-से-अनेक हैं; और साथ ही, kc_data के विरुद्ध फ़ाइलें एक-से-अनेक हैं। LEFT JOIN
एक और संकेत है कि पहली तालिका और दूसरी तालिका के बीच संबंध एक-से-अनेक है; हालांकि यह निश्चित नहीं है, कुछ कोडर बस सब कुछ LEFT JOIN
के साथ लिखते हैं . आपकी क्वेरी में आपके LEFT JOIN में कुछ भी गलत नहीं है, लेकिन अगर आपकी क्वेरी में कई एक-से-अनेक टेबल हैं, तो यह निश्चित रूप से विफल हो जाएगी, आपकी क्वेरी अन्य पंक्तियों के विरुद्ध दोहराई जाने वाली पंक्तियों का उत्पादन करेगी।
from
files
left join
dm_data ON dm_data.id = files.id
left join
kc_data ON kc_data.id = files.id
तो इस ज्ञान के साथ कि आप इंगित करते हैं कि फ़ाइलें dm_data के विरुद्ध एक-से-कई हैं, और यह kc_data के विरुद्ध भी एक-से-कई है। हम यह निष्कर्ष निकाल सकते हैं कि उन लोगों को एक अखंड क्वेरी पर समूहबद्ध करने और उन्हें समूहबद्ध करने में कुछ गड़बड़ है।
एक उदाहरण यदि आपके पास तीन टेबल हैं, अर्थात् ऐप (फ़ाइलें), ios_app (dm_data), android_app (kc_data), और यह ios के लिए उदाहरण के लिए डेटा है:
test=# select * from ios_app order by app_code, date_released;
ios_app_id | app_code | date_released | price
------------+----------+---------------+--------
1 | AB | 2010-01-01 | 1.0000
3 | AB | 2010-01-03 | 3.0000
4 | AB | 2010-01-04 | 4.0000
2 | TR | 2010-01-02 | 2.0000
5 | TR | 2010-01-05 | 5.0000
(5 rows)
और यह आपके Android के लिए डेटा है:
test=# select * from android_app order by app_code, date_released;
.android_app_id | app_code | date_released | price
----------------+----------+---------------+---------
1 | AB | 2010-01-06 | 6.0000
2 | AB | 2010-01-07 | 7.0000
7 | MK | 2010-01-07 | 7.0000
3 | TR | 2010-01-08 | 8.0000
4 | TR | 2010-01-09 | 9.0000
5 | TR | 2010-01-10 | 10.0000
6 | TR | 2010-01-11 | 11.0000
(7 rows)
यदि आप केवल इस क्वेरी का उपयोग करते हैं:
select x.app_code,
count(i.date_released) as ios_release_count,
count(a.date_released) as android_release_count
from app x
left join ios_app i on i.app_code = x.app_code
left join android_app a on a.app_code = x.app_code
group by x.app_code
order by x.app_code
इसके बजाय आउटपुट गलत होगा:
app_code | ios_release_count | android_release_count
----------+-------------------+-----------------------
AB | 6 | 6
MK | 0 | 1
PM | 0 | 0
TR | 8 | 8
(4 rows)
आप कार्टेशियन उत्पाद के रूप में जंजीर से जुड़ने के बारे में सोच सकते हैं, इसलिए यदि आपके पास पहली तालिका में 3 पंक्तियाँ हैं, और दूसरी तालिका में 2 पंक्तियाँ हैं, तो आउटपुट 6
होगा।
यहां विज़ुअलाइज़ेशन है, देखें कि प्रत्येक आईओएस एबी के लिए 2 दोहराए जाने वाले एंड्रॉइड एबी हैं। 3 ios AB हैं, तो जब आप COUNT(ios_app.date_released) करते हैं तो काउंट क्या होगा? वह 6 हो जाएगा; COUNT(android_app.date_released)
. के साथ भी ऐसा ही है , यह भी 6 होगा। इसी तरह प्रत्येक आईओएस टीआर के लिए 4 दोहराए जाने वाले एंड्रॉइड टीआर हैं, आईओएस में 2 टीआर हैं, जिससे हमें 8 की गिनती मिल जाएगी।
.app_code | ios_release_date | android_release_date
----------+------------------+----------------------
AB | 2010-01-01 | 2010-01-06
AB | 2010-01-01 | 2010-01-07
AB | 2010-01-03 | 2010-01-06
AB | 2010-01-03 | 2010-01-07
AB | 2010-01-04 | 2010-01-06
AB | 2010-01-04 | 2010-01-07
MK | | 2010-01-07
PM | |
TR | 2010-01-02 | 2010-01-08
TR | 2010-01-02 | 2010-01-09
TR | 2010-01-02 | 2010-01-10
TR | 2010-01-02 | 2010-01-11
TR | 2010-01-05 | 2010-01-08
TR | 2010-01-05 | 2010-01-09
TR | 2010-01-05 | 2010-01-10
TR | 2010-01-05 | 2010-01-11
(16 rows)
तो आपको क्या करना चाहिए प्रत्येक परिणाम को अन्य तालिकाओं और प्रश्नों में शामिल करने से पहले समतल करें।
यदि आपका डेटाबेस सीटीई के लिए सक्षम है, तो कृपया इसका उपयोग करें। यह बहुत साफ-सुथरा और बहुत ही स्व-दस्तावेजीकरण है:
with ios_app_release_count_list as
(
select app_code, count(date_released) as ios_release_count
from ios_app
group by app_code
)
,android_release_count_list as
(
select app_code, count(date_released) as android_release_count
from android_app
group by app_code
)
select
x.app_code,
coalesce(i.ios_release_count,0) as ios_release_count,
coalesce(a.android_release_count,0) as android_release_count
from app x
left join ios_app_release_count_list i on i.app_code = x.app_code
left join android_release_count_list a on a.app_code = x.app_code
order by x.app_code;
जबकि यदि आपके डेटाबेस में अभी तक कोई सीटीई क्षमता नहीं है, जैसे कि MySQL, तो आपको इसके बजाय ऐसा करना चाहिए:
select x.app_code,
coalesce(i.ios_release_count,0) as ios_release_count,
coalesce(a.android_release_count,0) as android_release_count
from app x
left join
(
select app_code, count(date_released) as ios_release_count
from ios_app
group by app_code
) i on i.app_code = x.app_code
left join
(
select app_code, count(date_released) as android_release_count
from android_app
group by app_code
) a on a.app_code = x.app_code
order by x.app_code
वह क्वेरी और CTE-शैली की क्वेरी सही आउटपुट दिखाएगी:
app_code | ios_release_count | android_release_count
----------+-------------------+-----------------------
AB | 3 | 2
MK | 0 | 1
PM | 0 | 0
TR | 2 | 4
(4 rows)
लाइव परीक्षण
गलत क्वेरी:http://www.sqlfiddle.com/#!2/9774a/ 2
सही क्वेरी:http://www.sqlfiddle.com/#!2/9774a/ 1