मेरे पास तीन टेबल हैं।


Table: "Foods"
-----------
ID    Name
-----------
1     Apple
2     Strawberry
3     Celery
4     Peanuts
5     Toffee

Table: "Tags"
------------
ID     Name
------------
A      Sweet
B      Fruit
C      Crunchy

Table: "Mappings"
-------------------------
ID    TagID     FoodID
-------------------------
101   A          1
102   A          2
103   A          5
104   B          2   
105   C          1
106   C          3
107   C          4
108   C          5

मैं एक क्वेरी चलाने और इस तरह स्वरूपित परिणाम प्राप्त करने का प्रयास कर रहा हूं:

** DESIRED RESULTS OUTPUT FORMAT **
------------------------------------------------------
ID    Name          IsSweet     IsFruit     IsCrunchy
------------------------------------------------------
1     Apple               1           1             1
2     Strawberry          1           1             0
3     Celery              0           0             1
4     Peanuts             0           0             1
5     Toffee              1           0             1

यहां वह क्वेरी है जिसका मैं वर्तमान में उपयोग कर रहा हूं जो काम नहीं कर रही है मैं कैसे चाहूंगा:

SELECT foods.id, foods.name, 
  IF(tags.name = "Sweet", 1, 0) IsSweet, 
  IF(tags.name = "Fruit", 1, 0) IsFruit,
  IF(tags.name="Crunchy", 1, 0) IsCrunchy,
  from Foods, Tags, Mappings 
    where Foods.ID = Mappings.FoodID and Mappings.TagID = Tags.ID

मुझे निम्नलिखित जैसे परिणाम मिल रहे हैं, जहां प्रत्येक खाद्य पदार्थ को एन बार दोहराया जाता है, एक बार मौजूद प्रत्येक टैग के लिए।

** ACTUAL RESULTS I'M GETTING **
------------------------------------------------------
ID    Name          IsSweet     IsFruit     IsCrunchy
------------------------------------------------------
1     Apple               1           0             0
1     Apple               0           1             0
1     Apple               0           0             1
2     Strawberry          1           0             0
2     Strawberry          0           1             0
3     Celery              0           0             1
4     Peanuts             0           0             1
5     Toffee              1           0             0
5     Toffee              0           0             1

मैं अपनी पसंद के परिणामों को स्वरूपित करने के लिए अपनी क्वेरी कैसे लिख सकता हूं? मैंने आउटर जॉइन की कोशिश की है, और CASE/WHEN स्टेटमेंट या GROUP BY का उपयोग करने की कोशिश की है, लेकिन मुझे अभी तक इसका पता नहीं चला है।

क्या कोई कृपया मेरे लिए कुछ दिशा प्रदान कर सकता है?

1
JCB 22 अगस्त 2018, 06:00
एप्लिकेशन कोड में डेटा डिस्प्ले के मुद्दों को संभालने पर विचार करें
 – 
Strawberry
22 अगस्त 2018, 08:57

3 जवाब

अधिकतम लागू करें:

   SELECT foods.id, foods.name, 
        max(IF(tags.name = "Sweet", 1, 0)) IsSweet, 
        max(IF(tags.name = "Fruit", 1, 0)) IsFruit,
        max(IF(tags.name="Crunchy", 1, 0)) IsCrunchy
   from Foods, Tags, Mappings 
   where Foods.ID = Mappings.FoodID and Mappings.TagID = Tags.ID
   group by foods.id, foods.name
0
dandarc 22 अगस्त 2018, 06:06

तालिकाओं की सूची को अलग करने के लिए कभी भी अल्पविराम का उपयोग न करें। हमेशा JOINS का प्रयोग करें जैसे:

SELECT foods.id, foods.name, 
  MAX(IF(tags.name = "Sweet", 1, 0)) IsSweet, 
  MAX(IF(tags.name = "Fruit", 1, 0)) IsFruit,
  MAX(IF(tags.name="Crunchy", 1, 0)) IsCrunchy,
  from Foods
  left join Mappings on Foods.ID = Mappings.FoodID 
  left join Tags on Mappings.TagID = Tags.ID
  group by foods.id

यह वास्तव में स्पष्ट और कुशल बनाता है कि टेबल कैसे संबंधित हैं। अन्य परिणाम एक कार्टेशियन उत्पाद है और where केवल इसके आउटपुट को फ़िल्टर करता है (जो कि गलत परिणाम है)।

स्टैक ओवरफ्लो में आपका स्वागत है।

संपादित करें: विवाद के अनुसार बाएं जुड़ते हैं

0
danblack 22 अगस्त 2018, 07:49
@ dandarc के उत्तर की तुलना में (कि मैंने MAX बिट्स को कॉपी किया है), मैंने केवल food.id द्वारा इसे एक विशिष्ट पहचानकर्ता के रूप में समूहीकृत किया है, इसलिए भोजन तालिका में किसी और चीज़ द्वारा समूहित करने की कोई आवश्यकता नहीं है।
 – 
danblack
22 अगस्त 2018, 06:10
मैं मुख्य रूप से ओरेकल में काम करता हूं, जो अक्सर मुझे एक त्रुटि देता है यदि मैं समूह में सब कुछ शामिल नहीं करता हूं जो कि एक समग्र कार्य में नहीं है। तो मैं इसे डिफ़ॉल्ट रूप से करता हूं। जबकि मैं स्पष्टता के लिए 'जॉइन' सिंटैक्स पसंद करता हूं, मैं असहमत हूं कि "कार्टेशियन उत्पाद और फ़िल्टर" गलत परिणाम देता है - आंतरिक जुड़ाव के लिए, जैसे कि हमारे यहां है, वे तार्किक रूप से समकक्ष हैं। कई डेटाबेस किसी भी तरह से एक ही निष्पादन योजना के साथ आएंगे।
 – 
dandarc
22 अगस्त 2018, 06:19
धन्यवाद - यह काम करता है! लेकिन अब मेरे पास एक और सवाल है। यदि मेरे पास एक Foods पंक्ति है जिसमें कोई संगत Tags नहीं है, तो मैं उस भोजन को आउटपुट परिणामों में भी दिखाने के लिए कैसे प्राप्त कर सकता हूं?
 – 
JCB
22 अगस्त 2018, 06:30
1
इनर जॉइन के बजाय लेफ्ट आउटर जॉइन करें। मूल जुड़ाव के लिए w3Schools में एक अच्छा ग्राफिक है - w3schools.com/sql/sql_join.asp< /ए>
 – 
dandarc
22 अगस्त 2018, 06:46
धन्यवाद - यह एकदम सही है। मैंने पहले बाएं बाहरी जुड़ने की कोशिश की और फिर मैं सोच रहा था कि मुझे दाएं बाहरी जुड़ने की जरूरत है, लेकिन दो बाएं बाहरी जुड़ने की बिल्कुल जरूरत है। आपकी मदद की बहुत सराहना करते हैं।
 – 
JCB
22 अगस्त 2018, 06:55

सबसे पहले, FROM खंड में अल्पविराम का उपयोग कभी नहीं करें। हमेशा उचित, स्पष्ट, मानक JOIN सिंटैक्स का उपयोग करें।

दूसरा, आप इस तथ्य का उपयोग करके अपने तर्क को सरल बना सकते हैं कि MySQL बूलियन मानों को पूर्णांक के रूप में मानता है।

तीसरा, आपको GROUP BY चाहिए:

और अंत में, SQL में स्ट्रिंग्स के लिए मानक सीमांकक एकल उद्धरण है। हालाँकि MySQL दोहरे उद्धरण चिह्नों का भी समर्थन करता है, आपको एकल उद्धरणों का उपयोग करने की आदत डाल लेनी चाहिए।

इसलिए:

select f.id, f.name, 
       max(t.name = 'Sweet') as IsSweet, 
       max(t.name = 'Fruit') as IsFruit,
       max(t.name = 'Crunchy') as IsCrunchy
from Foods f join
     Mappings m
     on f.ID = m.FoodID join
     Tags t
     on t.ID = m.TagID
group by f.id, f.name
0
Gordon Linoff 22 अगस्त 2018, 14:40