SQLITE: टैग और उत्पादों की समस्या


10

मैं निम्नलिखित करने के लिए एक क्वेरी बनाने का तरीका खोज रहा हूँ:

आइए 3 तालिकाओं पर विचार करें:

  • उत्पादों: उत्पादों की सूची
  • टैग: टैग की सूची
  • tag_ties: तालिका का उपयोग किसी उत्पाद को टैग जोड़ने के लिए किया जाता है

आइए प्रत्येक तालिका के लिए इस संरचना पर विचार करें:

उत्पाद:

  • आईडी (इंट, ऑटोइन्क्रिमेंट)
  • नाम (varchar, उत्पाद का नाम)

टैग:

  • आईडी (इंट ऑटोइन्क्रिमेंट)
  • लेबल (varchar, टैग का लेबल)

Tag_ties:

  • आईडी (इंट, ऑटोइन्क्रिमेंट)
  • टैग_आईडी (उदाहरण, टैग आईडी का संदर्भ)
  • Ref_id (int, एक उत्पाद आईडी का संदर्भ)

मैं क्या चाहता हूँ:

उदाहरण के लिए टैग 10, 11 और 12 के साथ टैग किए गए सभी उत्पादों को प्राप्त करें।

यह क्वेरी काम नहीं करती है, क्योंकि यह कम से कम टैग वाले उत्पादों को लौटाती है:

select 
    p.name as name,
    p.id as id
from 
    products p inner join tag_ties ties
on
    p.id=ties.ref_id
where
    ties.ref_id=p.id and
    ties.tag_id in (10,11,12)
group by 
    p.id
order by 
    p.name asc

जवाबों:


9

कुछ इस तरह की कोशिश करो:

select
    t1.id,
    t1.name
from
    (
    select
        p.name as name,
        p.id as id
    from
        products p inner join tag_ties ties
    on
        p.id=ties.ref_id
    where
        ties.tag_id in (10,11,12)
    ) as t1
group by
    t1.id,
    t1.name
having
    count(t1.id) = 3
order by
    t1.name asc
;

यह काम कर रहा है :)
जुलिएन एल

11

आप इंटरसेक्ट स्टेटमेंट्स का उपयोग करके इस समस्या को हल कर सकते हैं। प्रत्येक tag_id के लिए एक अलग चयन करें और उन्हें इंटरसेक्ट्स के साथ जोड़ दें और आपको केवल वे रिकॉर्ड मिलेंगे जो सभी तीन टैग_िड्स से मेल खाते हैं।

select products.id, products.name from 
products join tag_ties
on tag_ties.ref_id = products.id
where tag_ties.tag_id = 10
intersect
select products.id, products.name from 
products join tag_ties
on tag_ties.ref_id = products.id 
where tag_ties.tag_id = 11
intersect
select products.id, products.name from 
products join tag_ties
on tag_ties.ref_id = products.id 
where tag_ties.tag_id = 12

यहाँ प्रतिच्छेदन का उपयोग करने पर एक संदर्भ लेख है

इस लुक को थोड़ा अच्छा बनाने के लिए आप एक अस्थायी दृश्य का भी उपयोग कर सकते हैं।

create temporary view temp_view as 
select name, products.id as id, tag_ties.tag_id as tag_id 
from products join tag_ties
on tag_ties.ref_id = products.id

select name, id from temp_view where tag_id = 10
intersect ...

8

चयनित उत्तर से उपशम की आवश्यकता नहीं है। सभी दिए गए टैग आईडी के साथ उत्पादों का चयन करने के लिए क्वेरी बस हो सकती है:

SELECT 
    p.*
FROM 
    products AS p
INNER JOIN
    tag_ties AS tt
ON
    tt.ref_id = p.id
AND 
    tt.tag_id IN (10, 11, 12)
GROUP BY 
    p.id
HAVING 
    COUNT(p.id)=3

इस विचार का विस्तार करते हुए, हम एक ही शॉट में टैग लेबल के आधार पर भी प्रश्न कर सकते हैं। टैग के साथ उत्पादों का चयन करने के लिए ('foo', 'bar', 'baz'):

SELECT 
    p.*
FROM 
    products AS p
INNER JOIN
    tags AS t
ON
    t.label IN ('foo', 'bar', 'baz')
INNER JOIN
    tag_ties AS tt
ON
    tt.ref_id = p.id
AND 
    tt.tag_id = t.id
GROUP BY 
    p.id
HAVING 
    COUNT(p.id)=3

इसे थोड़ा जटिल करने के लिए, हम चौराहे ( AND) और संघ ( OR) को मिलाने के लिए एक उपकेंद्र का उपयोग कर सकते हैं । नीचे दिए गए क्वेरी समूह के सभी टैग ('foo', 'bar')और समूह के कम से कम एक टैग के साथ उत्पादों को लौटाएंगे ('baz', 'ding'):

SELECT 
    p.*
FROM 
    (
    SELECT 
        p.*
    FROM 
        products AS p
    INNER JOIN 
        tags AS t
    ON
        t.label IN ('foo', 'bar')
    INNER JOIN 
        tag_ties AS tt
    ON
        tt.ref_id = p.id
    AND 
        tt.tag_id = t.id
    GROUP BY 
        p.id
    HAVING 
        COUNT(p.id)=2
    ) AS p
INNER JOIN 
    tags AS t
ON 
    t.label IN ('baz', 'ding')
INNER JOIN
    tag_ties AS tt
ON
    tt.ref_id = p.id
AND 
    tt.tag_id = t.id
GROUP BY 
    p.id

2
आप एक की जरूरत नहीं है JOIN? नहीं, तकनीकी रूप से आप नहीं हैं, लेकिन क्या इसका उपयोग नहीं करने का कोई कारण है? और SQL-89 के लिए वापस जा रहे हैं निहितार्थ के संकेत?
ypercube y

5
मैं नीचा दिखा रहा हूं क्योंकि आपको हमेशा JOIN का इस्तेमाल करना चाहिएstackoverflow.com/questions/5654278/… एक स्पष्ट JOIN के बिना, आपका कोड मेरी दुकान में तैनात नहीं किया जाएगा
gbn

3
हे दोस्तों, मुझे यह बताने के लिए धन्यवाद कि निहित जोड़ खराब शैली हैं। मेरा मुख्य रूप से यह कहना था कि चयनित उत्तर से उपशम आवश्यक नहीं था। मैंने जॉइन करने के उत्तर का संपादन किया। यदि आपको मेरे प्रश्नों में कुछ और गलत दिखता है तो कृपया मुझे बताएं।
मोरेस

5
+1 बिना परेशान हुए और वास्तव में सलाह लेने के लिए अपने कौशल में सुधार के लिए सलाह ले रहा है।
ज़ेन

2
@Zane ने क्या कहा। +1 भी
जीबीएन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.