2009-04-21 15 views
9

मुझे तालिका ए और बी में शामिल होने वाली क्वेरी से केवल पहली पंक्ति चुननी होगी। तालिका बी पर एक ही नाम के साथ कई रिकॉर्ड मौजूद हैं। दो टेबलों में से किसी एक में पहचानकर्ता नहीं हैं। मैं इस योजना को या तो नहीं बदल सकता क्योंकि मेरे पास डीबी नहीं है।एक कथन में दो तालिकाओं के जुड़ने में पहली पंक्ति का चयन करें

TABLE A 
NAME 

TABLE B 
NAME 
DATA1 
DATA2 

Select Distinct A.NAME,B.DATA1,B.DATA2 
From A 
Inner Join B on A.NAME = B.NAME 

यह मैं

NAME  DATA1 DATA2 
sameName 1  2 
sameName 1  3 
otherName 5  7 
otherName 8  9 

देता है, लेकिन मैं नाम में केवल एक पंक्ति को पुनः प्राप्त करने की जरूरत है

NAME  DATA1 DATA2 
sameName 1  2 
otherName 5  7 

मैं एक के साथ एक अस्थायी तालिका में परिणाम जोड़ कर ऐसा करने में सक्षम था पहचान कॉलम और फिर प्रति नाम न्यूनतम आईडी का चयन करें।

समस्या यह है कि मुझे इसे एक ही कथन में करने की आवश्यकता है।

उत्तर

0

सुनिश्चित नहीं है कि यह आपकी समस्या का समाधान करेगा या नहीं, लेकिन आप नाम कॉलम में समूह द्वारा ग्रुप बाय क्लॉज और समूह का उपयोग करने का प्रयास कर सकते हैं।

DB2 Group by tutorial

7

एक समूह द्वारा का उपयोग करते हुए आपको इस प्रक्रिया हिस्सा मिल सकता है, लेकिन सावधान रहना। आप कुछ इस तरह करते हैं:

NAME  DATA1 DATA2 
    sameName 1  2  
    otherName 5  7 

लेकिन केवल डेटा आप के साथ परीक्षण कर रहे हैं की वजह से:

Select A.NAME, min(B.DATA1), min(B.DATA2) 
From A Inner Join B on A.NAME = B.NAME 
Group by A.NAME; 

आप परिणाम आप देख रहे हैं मिल जाएगा। यदि आप डेटा को बदलते हैं ताकि बजाय:

otherName 8  9 

आप था:

otherName 8  4 

यह वापसी होगी:

NAME  DATA1 DATA2 
    sameName 1  2  
    otherName 5  4 

ध्यान दें कि otherName data1 और DATA2 वापस नहीं करता है से एक ही रिकॉर्ड!

अद्यतन: डेटा मानों में से एक पर एक तुलना के साथ एक स्वयं में शामिल होने के रूप में, आप मदद कर सकते हैं:

SELECT a.*, b.* FROM a,b 
    LEFT JOIN b b2 ON b.name = b2.name AND b.data2 < b2.data2 
    WHERE a.name = b.name AND b2.data2 IS NOT NULL; 

बहरहाल, यह केवल तभी कार्य करेगा DATA2 में मानों नाम प्रति अद्वितीय हैं।

+0

अंतिम विवरण पर एक छोटा टाइपो है। यह "नॉट में" के बजाय "पूर्ण नहीं है" होना चाहिए। – mbp

+0

+1 आप एक उद्धारक हैं। आपका संपादित स्वयं एसक्यूएल सीई के साथ भी काम करता है जहां इस प्रश्न के अन्य समाधान एसक्यूएल सीई की सीमाओं के कारण नहीं हैं। –

0

यदि आप एक temp तालिका में जोड़ सकते हैं और फिर उससे पूछ सकते हैं, तो आप इसे एक ही समय में कर सकते हैं।

WITH T AS (temp table select), RN AS (select min row-numbers from T) SELECT T.NAME, T.DATA1, T.DATA2 FROM T INNER JOIN RN on T.row_number = RN.row_number 

इसे लिखने के कई अन्य तरीके हैं, लेकिन इस तरह मैं इसी तरह की चीजें कर रहा हूं।

0

कोशिश इस

SELECT A.NAME, bb.DATA1, bb.DATA2 
FROM A 
JOIN B bb 
ON  A.NAME = B.NAME 
WHERE NOT EXISTS (SELECT * 
        FROM B 
        WHERE NAME = bb.NAME 
          AND (DATA1 > bb.DATA1 
           OR DATA1 = bb.DATA1 AND DATA2 > bb.DATA2))

की तरह बी डेड्यूप के लिए अधिक या खंड अगर अधिक Datax कॉलम मौजूद जोड़ें।

यदि ए में डुप्लिकेट भी शामिल है, तो बस ओपी में DISTINCT का उपयोग करें।

10

यह काम करेगा:

with temp as (
    select A.NAME, B.DATA1, B.DATA2, 
     row_number() over (partition by A.NAME order by A.NAME) as rownum 
    from TABLEA A inner join TABLEB B 
    on A.NAME = B.NAME 
) 
select NAME, DATA1, DATA2 from temp where rownum = 1 

आप data1 के कम से कम मूल्य का चयन करना चाहते हैं और यह data2 भीतर है, तो इस बदलाव का उपयोग करें:

with temp as (
    select A.NAME, B.DATA1, B.DATA2, 
     row_number() over (partition by A.NAME order by B.DATA1, B.DATA2) as rownum 
    from TABLEA A inner join TABLEB B 
    on A.NAME = B.NAME 
) 
select NAME, DATA1, DATA2 from temp where rownum = 1 

दोनों प्रश्नों प्रति एक पंक्ति दे देंगे नाम।

+0

'बीनाम' द्वारा विभाजन करना बेहतर होगा, ताकि आप एक अनुक्रमणिका का उपयोग कर सकें (यदि कोई मौजूद है)। आपको रिपोर्टिंग 'एनाम' (तुलना के कारण) को भी परेशान नहीं करना पड़ेगा। –

+1

ग्रेट समाधान। धन्यवाद। –

+1

@ KobyDouek खुश है कि यह मदद की :) चीयर्स! –

0
SELECT A.NAME, bb.DATA1, bb.DATA2 
From A Inner Join B on A.NAME = B.NAME 
WHERE B.DATA1 = (SELECT MIN(DATA1) FROM B WHERE NAME = A.NAME) 

यह आपके वांछित परिणाम, केवल अन्य तरह से मैं जानता हूँ कि उपयोग कर रहा है दे देंगे, उपलब्ध कराने के B.DATA1 मूल्यों तालिका ए

से संबंधित वे अद्वितीय नहीं कर रहे हैं सेट के भीतर अद्वितीय हैं क्रॉस एमएसएसएलएल 2005 और ऊपर में लागू करें।

0

इस सवाल का टैग इंगित करता है कि यह डीबी 2 के लिए एक समाधान होगा, लेकिन यह बहुत ही MS-एसक्यूएल सर्वर के समान है, यदि ऐसा है तो ये समाधान आज़माएं:

क्रॉस का उपयोग करना, यह क्या प्रदर्शित करने के लिए संभव हो जाएगा केवल दोनों तालिकाओं

select A.*, B.DATA1, B.DATA2 
from A 
cross apply (select top 1 * from B where B.name = A.name) B 

में मौजूद है लेकिन यह बाध्यता के बिना प्रदर्शित करने के लिए क्या एक में मौजूद बाहरी को बदलने के लिए बी

select A.*, B.DATA1, B.DATA2 
from A 
OUTER apply (select top 1 * from B where B.name = A.name) B 

में मौजूद संरचना में संभव है लागू कथन के बाद, ऑर्डर स्टेटमेंट को शामिल करना भी संभव होगा, क्योंकि तालिका बी

0

में बाहर निकलने के क्रम का कोई संकेत नहीं है, आप प्रत्येक नाम के लिए एक पंक्ति प्राप्त करने के लिए पंक्ति संख्या का उपयोग कर सकते हैं, कुछ ऐसा करने का प्रयास करें

Select name,data1,data2 from 
(Select A.NAME,B.DATA1,B.DATA2,row_number() over(partitioj by a.name order by a.name) rn 
From A 
Inner Join B on A.NAME = B.NAME) where rn=1 
संबंधित मुद्दे