SQLZoo难题:获取在同一行共享ID的结果

时间:2015-10-30 21:01:24

标签: sql

http://sqlzoo.net/wiki/AdventureWorks_hard_questions

问题11指出:

  

对于在达拉斯拥有“主办公室”的每位客户,请显示“主办公室”的AddressLine1和“送货”地址的地址1 - 如果没有送货地址,请将其留空。每个客户使用一行。

相关表格/ ID是:

Customer             CustomerAddress              Address
Customer ID          CustomerID                   AddressID
                     AddressID                    AddressLine1
                     AddressType                  City

我目前的代码是

SELECT CA.CustomerID, 
CASE WHEN CA.AddressType = 'Main Office' THEN A.AddressLine1 ELSE "" END, .
CASE WHEN CA.AddressType = 'Shipping' THEN A2.AddressLine1 ELSE "" END 
FROM Address A
JOIN CustomerAddress CA 
ON A.AddressID = CA.AddressID 
JOIN Address A2 
ON A.AddressID = A2.AddressID
WHERE A.City = 'Dallas'

达拉斯总共有5个主要办事处,只有一个有送货地址。

当我尝试“按客户ID分组”时,它只返回其中一个地址,即使我在上面的查询中搜索过它们。

如何让BOTH地址在同一行返回?

3 个答案:

答案 0 :(得分:2)

首先在cte中过滤来自达拉斯的客户。然后离开加入以查找他们的送货地址:

;with cte as(select ca.customerid, a.addressline1
             from customeraddress ca 
             join address a on ca.addressid = a.addressid
             where ca.addresstype = 'Main Office' and a.City = 'Dallas') 
select c.customerid,
       c.addressline1 as mainaddress,
       a.addressline1 as shippingaddress
from cte c
left join customeraddress ca on c.customerid = ca.customerid and 
                                ca.addresstype = 'Shipping'
left join address a on ca.addressid = a.addressid

答案 1 :(得分:0)

两周后,我终于明白了。

SELECT T0.MainAddress AS 'Main Address', 
       isnull(T1.ShippingAddress,' ') AS 'Shipping Address'
FROM (SELECT CA.CustomerID AS [CustomerID], A.AddressLine1 AS [MainAddress]
      FROM CustomerAddress CA
      INNER JOIN Address A 
          ON A.AddressID = CA.AddressID
      WHERE CA.AddressType = 'Main Office' 
          AND A.City = 'Dallas') T0
LEFT JOIN (SELECT CA.CustomerID AS [CustomerID], 
                  A.AddressLine1 AS [ShippingAddress]
           FROM CustomerAddress CA 
           INNER JOIN Address A
               ON A.AddressID = CA.AddressID
           WHERE CA.AddressType = 'Shipping'
               AND A.City = 'Dallas') T1 
     ON T0.CustomerID = T1.CustomerID

我最终只需要绘制两个不同的表来绘制,而不是尝试从现有数据中绘制。它与上面的答案类似,但实际上它在我工作的网站中起作用。

答案 2 :(得分:0)

将聚集函数与GROPING结合使用的替代方法。

    SELECT Cust.CustomerID
          ,MAX(CASE WHEN CustAddr.AddressType = 'Main Office' THEN Addr.AddressLine1 ELSE NULL END) as 'MainOffice'
          ,MAX(CASE WHEN CustAddr.AddressType = 'Shipping' THEN Addr.AddressLine1 ELSE NULL END) as 'Shipping'
    FROM  Customer as Cust INNER JOIN CustomerAddress as CustAddr ON (Cust.CustomerID = CustAddr.CustomerID)
                           INNER JOIN Address as Addr ON (Addr.AddressID = CustAddr.AddressID)
WHERE Addr.City = 'Dallas'
GROUP BY Cust.CustomerID;