我想不通过这个。我有这个问题:
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 :(得分:6)
你想要改变你的联接,所以它返回min(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 :(得分: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
答案 2 :(得分:1)
如果是SQL Server或具有公用表表达式(CTE)的其他版本,则可以执行以下操作。 CTE添加一个按人员分组并按address_type_id排序的行号列。主要查询被更改为从CTE返回每个人的第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
顺便说一下,如果你有没有地址的人物记录,你可能想要在地址表上将INNER JOIN更改为OUTER JOIN(在我的回答中为cte)。如果您的要求表明,这也适用于购买和产品的连接。