2010-11-29 11 views
5

के साथ SQL क्वेरी सहायता मैं इस के माध्यम से नहीं सोच सकता। मेरे पास यह प्रश्न है:गैर-अद्वितीय डुप्लिकेट

SELECT 
    p.person_id, 
    p.first_nm, 
    p.last_nm, 
    pu.purchase_dt, 
    pr.sku, 
    pr.description, 
    a.address_type_id, 
    a.city_cd, 
    a.state_cd, 
    a.postal_cd 
FROM 
    person p 
    INNER JOIN address a ON p.person_id = a.person_id 
    INNER JOIN purchase pu ON pu.person_id = p.person_id 
    INNER JOIN product pr ON pr.product_id = pu.product_id 

सरल पर्याप्त - मुझे केवल उन ग्राहकों के लिए जानकारी प्राप्त करने की आवश्यकता है जिन्हें हमने रिटर्न भेज दिया है। हालांकि, क्योंकि addressType तालिका के

AddressType 

address_type_id address_type_desc 
------------------------------------ 
1   Home 
2   Shipping 

कुछ ग्राहकों को पता तालिका में एक से अधिक पते, इस तरह गैर-अद्वितीय डुप्लिकेट प्रविष्टियों बनाने की है।

1,Smith, John, 12/01/2009, A12345, Purple Widget, 1, Anywhere, CA, 12345 
1,Smith, John, 12/01/2009, A12345, Purple Widget, 2, Somewhere, ID, 54321 

मैं सिर्फ एक पंक्ति/व्यक्ति वापस जाने के लिए क्वेरी मिलता है और घर का पता लौटने अगर अन्यथा उपलब्ध करने के लिए शिपिंग पते वापसी चाहते हैं।

यह काफी आसान लगता है, और शायद यह सिर्फ मेरी ठंडा है, लेकिन इससे मुझे कुछ हद तक खरोंच लग रहा है।

+0

क्या डीबी इंजन? – Lex

+0

और कितने पते हो सकते हैं: 0..एन, 1. एन या 1..2? – Lex

उत्तर

5
SELECT 
    p.person_id, 
    p.first_nm, 
    p.last_nm, 
    pu.purchase_dt, 
    pr.sku, 
    pr.description, 
    COALESCE(ha.address_type_id, sa.address_type_id) AS address_type_id 
    CASE WHEN ha.address_type_id IS NOT NULL THEN ha.city_cd ELSE sa.city_cd END AS city_cd, 
    CASE WHEN ha.address_type_id IS NOT NULL THEN ha.state_cd ELSE sa.state_cd END AS state_cd, 
    CASE WHEN ha.address_type_id IS NOT NULL THEN ha.postal_cd ELSE sa.postal_cd END AS postal_cd 
FROM 
    person p 
    LEFT JOIN address ha ON p.person_id = ha.person_id AND ha.address_type_id = 1 
    LEFT JOIN address sa ON p.person_id = sa.person_id AND sa.address_type_id = 2 
    INNER JOIN purchase pu ON pu.person_id = p.person_id 
    INNER JOIN product pr ON pr.product_id = pu.product_id 
6

आप उन सभी के बजाय अपने इतने में शामिल होने के लिए यह मिनट (addressID) रिटर्न बदलना चाहते हैं:

 INNER JOIN address a ON p.person_id = a.person_id 
     inner join (select person_id, min(address_type_id) as min_addr 
from address group by person_id) a_min 
on a.person_id = a_min.person_id and a.address_type_id = a_min.min_addr 
1

एसक्यूएल सर्वर, या आम तालिका भाव के साथ दूसरे संस्करण (CTE) हैं, तो आप निम्नलिखित कर सकता है। सीटीई एक पंक्ति-संख्या कॉलम जोड़ता है जिसे व्यक्ति द्वारा समूहीकृत किया जाता है और address_type_id द्वारा आदेश दिया जाता है। सीटीई से प्रत्येक व्यक्ति के लिए नंबर 1 पंक्ति वापस करने के लिए मुख्य क्वेरी बदल दी जाती है।

WITH cte AS 
    (
    SELECT 
     a.person_id, 
     a.address_type_id, 
     a.city_cd, 
     a.state_cd, 
     a.postal_cd, 
     ROW_NUMBER() over (PARTITION BY person_id ORDER BY address_type_id) AS sequence 
    FROM address a 
    INNER JOIN AddressType at ON a.address_type_id = at.address_type_id 
    ) 

    SELECT 
     p.person_id, 
     p.first_nm, 
     p.last_nm, 
     pu.purchase_dt, 
     pr.sku, 
     pr.description, 
     a.address_type_id, 
     a.city_cd, 
     a.state_cd, 
     a.postal_cd 
    FROM 
     person p 
     INNER JOIN cte a ON p.person_id = a.person_id 
     INNER JOIN purchase pu ON pu.person_id = p.person_id 
     INNER JOIN product pr ON pr.product_id = pu.product_id 
    WHERE 
     a.sequence = 1 

वैसे, अगर आप व्यक्ति के रिकॉर्ड कोई पता है कि है, आप आंतरिक एक बाहरी करने के लिए शामिल हों बदलने के लिए चाहते हो सकता है पतों की मेज पर JOIN (मेरा उत्तर में CTE)। यदि आपकी आवश्यकताओं को इंगित करता है तो यह खरीद और उत्पाद में शामिल होने के लिए भी उपयुक्त हो सकता है।

संबंधित मुद्दे