बाएँ पहली पंक्ति में शामिल हों


138

मैंने बाईं ओर केवल पहली पंक्ति प्राप्त करने के बारे में कई सूत्र पढ़े, लेकिन, किसी कारण से, यह मेरे लिए काम नहीं करता है।

यहाँ मेरी संरचना है (पाठ्यक्रम का सरलीकृत)

फ़ीड

id |  title | content
----------------------
1  | Feed 1 | ...

कलाकार की

artist_id | artist_name
-----------------------
1         | Artist 1
2         | Artist 2

feeds_artists

rel_id | artist_id | feed_id
----------------------------
1      |     1     |    1 
2      |     2     |    1 
...

अब मैं लेखों को प्राप्त करना चाहता हूं और केवल पहले कलाकार से जुड़ना चाहता हूं और मैंने कुछ इस तरह से सोचा:

SELECT *
    FROM feeds 
    LEFT JOIN feeds_artists ON wp_feeds.id = (
        SELECT feeds_artists.feed_id FROM feeds_artists
        WHERE feeds_artists.feed_id = feeds.id 
    LIMIT 1
    )
WHERE feeds.id = '13815'

केवल फीड्स_आर्टिस्ट की केवल पहली पंक्ति प्राप्त करने के लिए, लेकिन पहले से ही यह काम नहीं करता है।

मैं TOPअपने डेटाबेस के कारण उपयोग नहीं कर सकता और मैं परिणाम को समूह में नहीं रख सकता feeds_artists.artist_idक्योंकि मुझे उन्हें तिथि के अनुसार क्रमबद्ध करने की आवश्यकता है (मुझे उन्हें इस प्रकार समूहित करके परिणाम मिले, लेकिन परिणाम जहां नवीनतम नहीं हैं)

OUTER APPLY के साथ भी कुछ करने की कोशिश की - कोई सफलता भी नहीं मिली। सच कहूं तो मैं वास्तव में उन पंक्तियों में क्या चल रहा है इसकी कल्पना नहीं कर सकता हूं - शायद सबसे बड़ा कारण है कि मुझे यह काम करने के लिए नहीं मिलता है।

उपाय:

SELECT *
FROM feeds f
LEFT JOIN artists a ON a.artist_id = (
    SELECT artist_id
    FROM feeds_artists fa 
    WHERE fa.feed_id = f.id
    LIMIT 1
)
WHERE f.id = '13815'


यहाँ समाधान stackoverflow.com/a/7588442/612987
वसीम ए।

आपको समाधान को एक उत्तर के रूप में रखना चाहिए ताकि हम इसे वोट कर सकें और यह भविष्य के आगंतुकों के लिए अधिक दिखाई दे सकता है
fguillen

मुझे लगता है कि आप सही हैं - मैंने इसे एक उत्तर के रूप में भी जोड़ा।
KddC

जवाबों:


97

यदि आप यह मान सकते हैं कि कलाकार आईडी समय के साथ बढ़ाते हैं, तो MIN(artist_id)यह जल्द से जल्द होगा।

तो कुछ इस तरह से आज़माएं (अप्रकाशित ...)

SELECT *
  FROM feeds f
  LEFT JOIN artists a ON a.artist_id = (
    SELECT
      MIN(fa.artist_id) a_id
    FROM feeds_artists fa 
    WHERE fa.feed_id = f.feed_id
  ) a

आपकी शीघ्र प्रतिक्रिया के लिए धन्यवाद। यह सटीक उत्तर नहीं था, लेकिन पूरी तरह से मुझे सही तरीके से मिला। मैंने हमेशा कोशिश की कि दोनों को एक ही स्तर पर शामिल किया जाए, बजाय एक को दूसरे से जोड़े रखने के। मुझे सही रास्ते पर लाने के लिए बहुत-बहुत धन्यवाद। पहली पोस्ट संपादित की
KddC

4
क्या इस बिंदु पर एक सरल उप-क्वेरी बेहतर नहीं होगी? क्योंकि अब आपके पास एक जॉइन और सब-क्वेरी है। बस कारण पूछ रहा हूँ मैं एक ही समस्या का हल ढूंढ रहा हूँ :)
galdikas

2
उपश्रेणी बहुत धीमी है।
सिनुक्स

1
@ साइनक्स "बहुत धीमी गति" को परिभाषित करता है। यह रिकॉर्ड की संख्या और दी गई आवश्यकताओं पर निर्भर करता है।
पर्यवेक्षक

1
यह काम नहीं करेगा! उप-क्वेरी माता-पिता क्वेरी से फ़ील्ड पर गुजरने की अनुमति नहीं देती है !!!
आरा सिंह

53

बिना सबसिले के संस्करण:

   SELECT f.title,
          f.content,
          MIN(a.artist_name) artist_name
     FROM feeds f
LEFT JOIN feeds_artists fa ON fa.feed_id = f.id
LEFT JOIN artists a ON fa.artist_id = a.artist_id
 GROUP BY f.id

2
मुझे नहीं लगता कि यह पहली पंक्ति होगी (पहली आईडी या किसी और चीज़ की पहली), यह बस बेतरतीब ढंग से बाईं बाईं पंक्तियों में से एक को चुनना है।
सिनुक्स

26
यह प्रश्न गलत है। यह "सबसे कम" कलाकार नाम का चयन करेगा जो सेट में पहले कलाकारों का नाम नहीं है।
ग्लेपा

5
प्रश्न के लिए गलत ... लेकिन वास्तव में मुझे क्या चाहिए। मेरे मामले में, मैं सिर्फ उस तालिका से पहली आईडी चाहता हूं, जिसमें मैं शामिल हो रहा हूं।
ड्रू स्टीफंस

2
यहाँ समस्या यह है कि यदि आप एक COUNT या SUM करने का निर्णय लेते हैं तो आपने डेटा खराब कर दिया होगा। Subselect के साथ समस्या यह है कि यह डेटा प्राप्त करने के लिए भारी है क्योंकि यह एक अस्थायी तालिका बनाई गई है ... काश MySql LEFT JOIN स्तर पर एक सीमा हो सकती है।
शैडोएब

इस समाधान में प्रदर्शन समस्या है। इसके बजाय मिन / मैक्स समाधान का उपयोग करें।
साडेघ पीएम

25

@ मैट डॉजेस जवाब ने मुझे सही रास्ते पर ला खड़ा किया। सभी उत्तरों के लिए फिर से धन्यवाद, जिसने इस समय में बहुत से लोगों की मदद की। यह इस तरह काम कर रहा है:

SELECT *
FROM feeds f
LEFT JOIN artists a ON a.artist_id = (
    SELECT artist_id
    FROM feeds_artists fa 
    WHERE fa.feed_id = f.id
    LIMIT 1
)
WHERE f.id = '13815'

यह केवल पहली पंक्ति के लिए काम करने का उत्तर है। कोई f.idशर्त नहीं होने पर टूट जाता है ।
ताजनगरी

2

मैंने कुछ और उपयोग किया है (मुझे बेहतर लगता है ...) और इसे साझा करना चाहते हैं:

मैंने एक ऐसा व्यू बनाया, जिसमें "समूह" खंड है

CREATE VIEW vCountries AS SELECT * PROVINCES GROUP BY country_code

SELECT * FROM client INNER JOIN vCountries on client_province = province_id

मैं अभी तक कहना चाहता हूं, कि मुझे लगता है कि हमें इस समाधान को करने की आवश्यकता है क्योंकि हम इस मामले में गलत काम कर रहे हैं ... कम से कम मेरे मामले में ... लेकिन कभी-कभी यह सब कुछ नया करने के लिए ऐसा करना सस्ता है ...

मुझे उम्मीद है यह मदद करेगा!


यह मानते हुए कि प्रत्येक के लिए कई पंक्तियाँ (प्रांत?) हैं country_code, जो GROUP BYअनुचित है। देख लो ONLY_FULL_GROUP_BY
रिक जेम्स

आप केवल LEFT / INNER JOIN के लिए उपयोग किए जाने के लिए एक दृश्य बनाने की ज़रूरत नहीं है ?! एक उपकेंद्र या एक WITH x AS (खंड का उपयोग कर सकते हैं ?
कीरादोटी

2

यहाँ कई उत्तरों के आधार पर, मुझे कुछ ऐसा मिला, जो मेरे लिए काम करता था और मैं चाहता था कि जो कुछ हो रहा है, उसे सामान्य और स्पष्ट करूँ।

कन्वर्ट:

LEFT JOIN table2 t2 ON (t2.thing = t1.thing)

सेवा:

LEFT JOIN table2 t2 ON (t2.p_key = (SELECT MIN(t2_.p_key) 
    FROM table2 t2_ WHERE (t2_.thing = t1.thing) LIMIT 1))

वह स्थिति जो t1 और t2 को जोड़ती है ON, को आंतरिक क्वेरी से और अंदर ले जाया जाता है WHEREMIN(primary key)या LIMIT 1बनाता है केवल 1 पंक्ति भीतरी क्वेरी द्वारा दिया जाता है सुनिश्चित करें कि।

एक विशिष्ट पंक्ति का चयन करने के बाद हमें ONयह बताने की आवश्यकता है कि वह कौन सी पंक्ति है। यही कारण ONहै कि इसमें शामिल होने की प्राथमिक कुंजी की तुलना की गई है।

आप आंतरिक क्वेरी (यानी ऑर्डर + सीमा) के साथ खेल सकते हैं, लेकिन इसमें वांछित पंक्ति की एक प्राथमिक कुंजी वापस करनी होगी ONजो सटीक पंक्ति को शामिल होने के लिए बताएगी ।


नोट्स: यह केवल LIMITया केवल के साथ भी काम करेगा MINONप्रदर्शन प्रभाव से बचने के लिए शर्त शामिल होने वाली प्राथमिक तालिका पर होनी चाहिए।
ओरिदम

1

मैं एक अधिक सामान्यीकृत उत्तर देना चाहता हूं । एक है कि किसी भी मामले को संभालना होगा जब आप एक बाएँ में केवल पहली आइटम का चयन करना चाहते हैं

आप एक सबक्वेरी का उपयोग कर सकते हैं जो GROUP_CONCATS जो आप चाहते हैं (सॉर्ट किया गया है!), तो बस GROUP_CONCAT'd को विभाजित करें और केवल इसका पहला आइटम लें, जैसे ...

LEFT JOIN Person ON Person.id = (
    SELECT SUBSTRING_INDEX(
        GROUP_CONCAT(FirstName ORDER BY FirstName DESC SEPARATOR "_" ), '_', 1)
    ) FROM Person
);

चूंकि हमारे पास ORDER BY विकल्प के रूप में DESC है , इसलिए यह "Zack" जैसे किसी व्यक्ति के लिए व्यक्ति आईडी लौटाएगा। अगर हम "एंडी" की तरह नाम के साथ किसी चाहता था, हम बदल जाएगा आदेश द्वारा प्रथम DESC करने के आदेश द्वारा प्रथम एएससी

यह फुर्तीला है, क्योंकि यह आपके हाथों के भीतर पूरी तरह से ऑर्डर करने की शक्ति रखता है। लेकिन, बहुत परीक्षण के बाद, यह बहुत सारी उपयोगकर्ताओं और बहुत सारे डेटा वाली स्थिति में अच्छा नहीं होगा

हालांकि, यह व्यवस्थापक के लिए डेटा-गहन रिपोर्ट चलाने में उपयोगी है।


GROUP_CONCATजब तक मानों की संख्या सीमित है चाल अच्छा है। डिफ़ॉल्ट सीमा 1024 वर्ण है।
रिक जेम्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.