Mysql में क्लॉज द्वारा यूनियन और ऑर्डर का उपयोग करना


123

मैं mysql क्वेरी में यूनियन के साथ ऑर्डर का उपयोग करना चाहता हूं। मैं अपनी साइट पर खोज के लिए दूरी के आधार पर विभिन्न मानदंडों के आधार पर विभिन्न प्रकार के रिकॉर्ड ला रहा हूं। पहला चुनिंदा क्वेरी सटीक स्थान खोज से संबंधित डेटा देता है। दूसरा चुनिंदा क्वेरी खोजे गए स्थान से 5 किलोमीटर के भीतर दूरी से संबंधित डेटा देता है। 3 चुनिंदा क्वेरी खोजे गए स्थान से 5-15 किलोमीटर के भीतर दूरी से संबंधित डेटा देता है।

फिर सभी परिणामों को मर्ज करने और पेजिंग के साथ एक पृष्ठ पर दिखाने के लिए संघ का उपयोग करके im। 'सटीक खोज परिणाम' , '5 किलोमीटर के भीतर परिणाम' आदि के रूप में उपयुक्त शीर्षक के तहत

अब मैं id या add_date के आधार पर परिणाम सॉर्ट करना चाहता हूं। लेकिन जब मैं अपनी क्वेरी के अंत में खंड द्वारा आदेश जोड़ देता हूं (क्वेरी 1 यूनियन क्वेरी 2 यूनियन क्वेरी 3 ऑर्डर add_date द्वारा)। यह सभी परिणामों को हल करता है। लेकिन मैं जो चाहता हूं वह यह है कि प्रत्येक शीर्षक के तहत छांटा जाए।


प्रत्येक तालिका में आप किस प्रकार (ओं) को रखना चाहते हैं?
user151841

जवाबों:


221

आप प्रत्येक चयनित के लिए एक छद्म-स्तंभ नाम रैंक जोड़कर ऐसा कर सकते हैं, कि आप अपने अन्य मानदंडों द्वारा छँटाई करने से पहले, पहले से क्रमबद्ध कर सकते हैं, जैसे:

select *
from (
    select 1 as Rank, id, add_date from Table 
    union all
    select 2 as Rank, id, add_date from Table where distance < 5
    union all
    select 3 as Rank, id, add_date from Table where distance between 5 and 15
) a
order by rank, id, add_date desc

9
क्यों aऔर अंत है?
उदय हिरावाले

25
MySQL के लिए आवश्यक है कि व्युत्पन्न तालिकाओं में एक उपनाम हो।
RedFilter

4
@RedFilter, मुझे यह बिलकुल नहीं आता। जब हम केवल सभी 3 तालिकाओं का चयन कर सकते हैं, तो "एक व्युत्पन्न तालिका के रूप में चयन करें" का पूरा बिंदु क्या है order by? ( "सॉर्ट करने के लिए या पूरी की सीमा UNIONपरिणाम, व्यक्तिगत बीच में लिखना SELECTबयान और जगह ORDER BYया LIMITपिछले एक के बाद" )। अपने कोड की तुलना i.stack.imgur.com/LpTMU.png
शाम

1
@ स्पेसर अगर वह वाक्य रचना MySQL के साथ काम करता है, तो इसके लिए जाएं! मेरा सिंटैक्स थोड़ा अधिक क्रॉस-प्लेटफ़ॉर्म है, मैं आमतौर पर MySQL के साथ काम नहीं करता। मैं वास्तव में इसे पसंद करता हूं, हालांकि, क्योंकि यह अधिक सामान्यीकृत मामलों में काम करता है, उदाहरण के लिए, विचार करें कि जब आप केवल पिछले दस से पहले दस मैच चाहते हैं, तो मुझे लगता है कि आपको वैसे भी मेरे वाक्यविन्यास में वापस आना होगा।
RedFilter

1
@Pacerier, यह भी विचार करें कि इस तरह से मूल्य उस शीर्ष "चयन *" की जगह "चयन आईडी, add_date" और स्ट्रिप "रैंक" को परिणाम से बाहर रखने की अनुमति देता है यदि आप उन्हें नहीं देखना चाहते हैं।
देव नल

45

आप ऐसा करने के लिए उपश्रेणियों का उपयोग कर सकते हैं:

select * from (select values1 from table1 order by orderby1) as a
union all
select * from (select values2 from table2 order by orderby2) as b

1
Tnx, अलग-अलग ऑर्डर करने के लिए अच्छा है। यदि आदेश खंड सामान्य था, तो भी हम एक अलग व्यवस्था कर सकते हैं, लेकिन हम परिणाम अलग करना चाहते हैं (आदेशों को अलग करने के बजाय): SELECT * FROM ( SELECT aaa AS Col, 1 AS Official FROM table1 UNION ALL SELECT bbb AS Col, 0 AS Official FROM table2 ) AS tbl ORDER BY Official, Col
Alix

18
यह गलत है : अलग-अलग वक्तव्यों के ORDER BYलिए उपयोग से SELECTतात्पर्य उस आदेश के बारे में कुछ भी नहीं है जिसमें पंक्तियाँ अंतिम परिणाम में दिखाई देती हैं
shmosel

आप सही हैं, स्वीकृत उत्तर भी सही है। यह सिर्फ तब अच्छा हुआ जब मैंने इसका परीक्षण किया।
रिकेटेफॉक्स

shmosel (और rickythefox) - संघ सभी डुप्लिकेट को नहीं हटाते हैं, और इसलिए आपके व्यक्तिगत सॉर्ट किए गए चयनों के प्रकार को बदलने का कोई कारण नहीं है। यही कारण है कि यह आपके लिए अतीत में काम करता था, और भविष्य में यह आपके लिए क्यों काम करेगा। अंतिम परिणाम में गड़बड़ किए जा रहे आदेश के कारण UNION (DISTINCT) को पंक्तियों को कुशलतापूर्वक संयोजित करने के लिए किसी प्रकार की आवश्यकता होती है। या अधिक विशेष रूप से, सॉर्ट करें क्योंकि यह पंक्तियों को कुशलता से जोड़ती है। इसलिए आप अपनी उपश्रेणियों को संरक्षित करने के लिए संघ पर निर्भर रह सकते हैं।
गेरार्ड ओनील

2
पुराने MySQL संस्करणों के लिए यह बहुत अच्छा काम कर रहा था, अब यह दृष्टिकोण काम नहीं करेगा । क्योंकि एसक्यूएल मानक सबक्वेरी के आदेश को संरक्षित करने की गारंटी नहीं देता है।
आंद्रेई

28
(select add_date,col2 from table_name) 
  union 
(select add_date,col2 from table_name) 
  union 
(select add_date,col2 from table_name) 

order by add_date

यह काम किया, लेकिन अजीब तरह से मुझे एक चीज को बदलने की जरूरत थी: मुझे उस क्षेत्र को एक साझा उर्फ ​​देने की जरूरत थी जो आदेश दे रहा था। इसके अलावा काम किया, धन्यवाद!
होल्डऑफ़हंगर

9

एक संघ क्वेरी में केवल एक मास्टर ORDER BYक्लॉज, IIRC हो सकता है। इस पाने के लिए, प्रत्येक अधिक से अधिक बनाने क्वेरी में UNIONक्वेरी, एक क्षेत्र है कि हो जाएगा एक क्षेत्र आप तरह से के लिए जोड़ने UNIONके ORDER BY

उदाहरण के लिए, आपके पास कुछ ऐसा हो सकता है

SELECT field1, field2, '1' AS union_sort
UNION SELECT field1, field2, '2' AS union_sort
UNION SELECT field1, field2, '3' AS union_sort
ORDER BY union_sort

वह union_sortक्षेत्र कुछ भी हो सकता है जिसे आप क्रमबद्ध करना चाहते हैं। इस उदाहरण में, यह पहली तालिका के पहले, दूसरे तालिका के दूसरे आदि से परिणाम डालने के लिए होता है।


9

मत भूलना, संघ सभी रिकॉर्ड करने के लिए एक रिकॉर्ड सेट करने के लिए एक तरह से जोड़ने या विलय के बिना जोड़ने का एक तरीका है (संघ के विपरीत)।

उदाहरण के लिए:

select * from (
    select col1, col2
    from table a
    <....>
    order by col3
    limit by 200
) a
union all
select * from (
    select cola, colb
    from table b
    <....>
    order by colb
    limit by 300
) b

यह अलग-अलग प्रश्नों को स्पष्ट रखता है और आपको प्रत्येक प्रश्न में अलग-अलग मापदंडों के आधार पर हल करने की अनुमति देता है। हालाँकि चयनित उत्तर के तरीके का उपयोग करने से यह जटिलता के आधार पर स्पष्ट हो सकता है और डेटा संबंधित है क्योंकि आप इस प्रकार की अवधारणा कर रहे हैं। यह आपको कृत्रिम कॉलम को क्वेरी प्रोग्राम में वापस करने की अनुमति देता है, इसलिए इसका एक संदर्भ है जो इसे क्रमबद्ध या व्यवस्थित कर सकता है।

लेकिन इस तरह से तेज़ होने का फायदा है, अतिरिक्त चर पेश नहीं करना, और प्रत्येक क्वेरी को सॉर्ट सहित अलग करना आसान बनाता है। एक सीमा जोड़ने की क्षमता बस एक अतिरिक्त बोनस है।

और निश्चित रूप से संघ को सभी को एक संघ में बदलने और संपूर्ण क्वेरी के लिए एक प्रकार जोड़ने के लिए स्वतंत्र महसूस करें। या एक कृत्रिम आईडी जोड़ें, इस मामले में यह प्रत्येक क्वेरी में विभिन्न मापदंडों द्वारा सॉर्ट करना आसान बनाता है, लेकिन यह अन्यथा स्वीकृत उत्तर के समान है।


4

मुझे यह ज्वाइन प्लस यूनियन में काम करने के लिए मिला।

(SELECT 
   table1.column1,
   table1.column2,
   foo1.column4
 FROM table1, table2, foo1, table5
 WHERE table5.somerecord = table1.column1
 ORDER BY table1.column1 ASC, table1.column2 DESC
)

UNION

(SELECT
    ... Another complex query as above
)

ORDER BY column1 DESC, column2 ASC

3

जब आप mysql ORDER BYके साथ संयोजन में उपयोग की जाने वाली उप क्वेरी के अंदर एक क्लॉज का उपयोग करते हैं, तो वह क्लॉज UNIONको अनुकूलित कर देगा ORDER BY

ऐसा इसलिए है क्योंकि डिफ़ॉल्ट रूप से UNIONरिटर्न एक अनियंत्रित सूची है इसलिए ORDER BYकुछ भी नहीं करेगा।

अनुकूलन का उल्लेख डॉक्स में किया गया है और कहता है:

किसी व्यक्ति के चयन के द्वारा आदेश या सीमा लागू करने के लिए, कोष्ठक के अंदर खंड रखें जो चयन को संलग्न करता है:

(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10) UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);

हालाँकि, व्यक्तिगत चयन के लिए ORDER BY के उपयोग से तात्पर्य उस क्रम के बारे में कुछ भी नहीं है जिसमें पंक्तियाँ अंतिम परिणाम में दिखाई देती हैं क्योंकि UNION डिफ़ॉल्ट रूप से पंक्तियों के अनियंत्रित सेट का उत्पादन करता है। इसलिए, इस संदर्भ में ORDER BY का उपयोग आम तौर पर LIMIT के साथ संयोजन के रूप में किया जाता है, ताकि इसका चयन SELECT को प्राप्त करने के लिए चयनित पंक्तियों के सबसेट को निर्धारित करने के लिए किया जाए, भले ही यह जरूरी न हो कि उन पंक्तियों के क्रम को प्रभावित न करें। अंतिम यूनिअन परिणाम। यदि ORDER BY किसी SELECT में LIMIT के बिना दिखाई देता है, तो इसे ऑप्टिमाइज़ किया जाता है क्योंकि इसका वैसे भी कोई प्रभाव नहीं होगा।

इसका अंतिम वाक्य थोड़ा भ्रामक है क्योंकि इसका प्रभाव होना चाहिए। यह अनुकूलन समस्या का कारण बनता है जब आप एक ऐसी स्थिति में होते हैं जहां आपको उप-क्षेत्र के भीतर ऑर्डर करने की आवश्यकता होती है।

MySQL को इस ऑप्टिमाइज़ेशन को न करने के लिए मजबूर करने के लिए आप एक लिमिट क्लॉज़ को जोड़ सकते हैं:

(SELECT 1 AS rank, id, add_date FROM my_table WHERE distance < 5 ORDER BY add_date LIMIT 9999999999)
UNION ALL
(SELECT 2 AS rank, id, add_date FROM my_table WHERE distance BETWEEN 5 AND 15 ORDER BY rank LIMIT 9999999999)
UNION ALL
(SELECT 3 AS rank, id, add_date from my_table WHERE distance BETWEEN 5 and 15 ORDER BY id LIMIT 9999999999)

एक उच्च का LIMITमतलब है कि आप OFFSETसमग्र क्वेरी पर जोड़ सकते हैं यदि आप कुछ ऐसा करना चाहते हैं जैसे पृष्ठ पर अंक लगाना।

यह आपको ORDER BYप्रत्येक संघ के लिए अलग-अलग कॉलम में सक्षम होने का अतिरिक्त लाभ भी देता है ।


0

प्रयत्न:

SELECT result.* 
FROM (
 [QUERY 1]
 UNION
 [QUERY 2]
) result
ORDER BY result.id

जहां [QUERY 1] और [QUERY 2] आपके दो प्रश्न हैं जिन्हें आप मर्ज करना चाहते हैं।


0

इसका कारण यह है कि आप पूरे परिणाम-सेट को क्रमबद्ध कर रहे हैं, आपको संघ के प्रत्येक भाग को अलग-अलग क्रमबद्ध करना चाहिए, या आप ORDER (कुछ का उपयोग कर सकते हैं)


0

मैंने यूनियन बनाने से पहले प्रत्येक प्रश्न द्वारा आदेश को जोड़ने की कोशिश की

(select * from table where distance=0 order by add_date) 
union 
(select * from table where distance>0 and distance<=5 order by add_date)

लेकिन यह काम नहीं कर रहा था। यह वास्तव में प्रत्येक चयन से पंक्तियों के भीतर ऑर्डरिंग नहीं करता था।

मुझे लगता है कि आपको आदेश को बाहर की तरफ रखना होगा और कॉलम को उस क्रम में जोड़ना होगा, जहां कुछ इस तरह हो

(select * from table where distance=0) 
union 
(select * from table where distance>0 and distance<=5) 
order by distance, add_date

यह थोड़ा मुश्किल हो सकता है, क्योंकि आप श्रेणियों के आधार पर समूह बनाना चाहते हैं, लेकिन मुझे लगता है कि यह उचित होना चाहिए।


user151841 Union_sort विचार समूहन को संभालने का एक अच्छा तरीका होगा
माइक C
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.