通过外键列获取多行
Fetching multiple rows by foreign key column
我有一个包含多个地址的地址 table
Address:
| Id | details | ... |
- - - - - - - - - - - - - - - -
| 1 | details | ... |
| 2 | details | ... |
| 3 | details | ... |
| 4 | details | ... |
然后我有一个站点 table,其中包含 address.id 作为代表帐单或送货地址的 FK,
Site:
| Id | details | Ship_Address_id | Bill_Address_id | ... |
- - - - - - - - - - - - - - - -
| 1 | details | 1 | 2 | |
| 2 | details | 1 | 3 | |
| 3 | details | 4 | 4 | |
| 4 | details | 2 | 3 | |
有没有办法连接两个 table 以便来自站点 table 的单行可以获取地址 table 的两行,即使是在地址相同的情况下两列。
我期待使用地址的多个站点连接,但这不起作用:
这是我试过的:
SELECT CASE
WHEN ship.CRM_Address_Internal_Id_Ship IS NOT NULL THEN 'Ship'
WHEN bill.CRM_Address_Internal_Id_Ship IS NOT NULL THEN 'Bill'
ELSE '' END
FROM Address as Adr
LEFT JOIN Site ship ON ship.Ship_Address_id = Adr.id
LEFT JOIN Site bill ON bill.Bill_Address_id = Adr.id
即使我不使用 CASE,它也不会为站点的每个地址获取两行。
请指教。
编辑
这是所需的输出 table:
与站点 table 一样,我们有两个不同的地址 ID table (Ship/Bill) 因此结果 table 应该为每个 site.id[=29= 显示两行]
例如,我正在获取 site.id 1 和 3 的记录,然后
Result_Table:
| Address.ID | Address Details | TYPE | ... |
--------------------------------------------
| 1 | Other Details | Ship | ... |
| 2 | Other Details | Bill | ... |
| 4 | Other Details | Ship | ... |
| 4 | Other Details | Bill | ... |
有多种方法可以做到这一点。这是我用UNPIVOT实现的一个例子,大家可以参考一下:
declare @address table(id int, details nvarchar(100))
declare @site table(id int, details nvarchar(100), ship_address_id int, bill_address_id int)
insert into @address values(1,'details 1')
insert into @address values(2,'details 2')
insert into @address values(3,'details 3')
insert into @address values(4,'details 4')
insert into @site values(1,'details 1',1,2)
insert into @site values(2,'details 1',1,3)
insert into @site values(3,'details 1',4,4)
insert into @site values(4,'details 1',2,5)
SELECT *
FROM (
SELECT s.id as site_id, s.bill_address_id, s.ship_address_id
FROM @Site AS s
INNER JOIN @Address AS sa ON s.Ship_Address_id = sa.Id
INNER JOIN @Address AS ba ON s.Bill_Address_id = ba.Id
WHERE s.id in (1,3)) p
UNPIVOT
(address_id FOR address_type IN
(Ship_Address_id, Bill_Address_id)
) AS unpvt
输出
site_id address_id address_type
1 1 ship_address_id
1 2 bill_address_id
3 4 ship_address_id
3 4 bill_address_id
您似乎在寻找 UNION ALL
,而且您的表格是倒着的。我认为您正在寻找更像这样的东西:
SELECT ship.id Site_id, CASE
WHEN ship.CRM_Address_Internal_Id_Ship IS NOT NULL THEN 'Ship'
ELSE 'No Ship' END AddressPresent
FROM Site ship
LEFT JOIN Address Adr ON ship.Ship_Address_id = Adr.id
UNION ALL
SELECT bill.id Site_id, CASE
WHEN bill.CRM_Address_Internal_Id_Ship IS NOT NULL THEN 'Bill'
ELSE 'No Bill' END AddressPresent
FROM Site bill
LEFT JOIN Address Adr ON bill.Bill_Address_id = Adr.id
我还想知道您是否有 'CRM_Address_Internal_Id_Bill' 列应该在查询的第二部分?
我有一个包含多个地址的地址 table
Address:
| Id | details | ... |
- - - - - - - - - - - - - - - -
| 1 | details | ... |
| 2 | details | ... |
| 3 | details | ... |
| 4 | details | ... |
然后我有一个站点 table,其中包含 address.id 作为代表帐单或送货地址的 FK,
Site:
| Id | details | Ship_Address_id | Bill_Address_id | ... |
- - - - - - - - - - - - - - - -
| 1 | details | 1 | 2 | |
| 2 | details | 1 | 3 | |
| 3 | details | 4 | 4 | |
| 4 | details | 2 | 3 | |
有没有办法连接两个 table 以便来自站点 table 的单行可以获取地址 table 的两行,即使是在地址相同的情况下两列。 我期待使用地址的多个站点连接,但这不起作用:
这是我试过的:
SELECT CASE
WHEN ship.CRM_Address_Internal_Id_Ship IS NOT NULL THEN 'Ship'
WHEN bill.CRM_Address_Internal_Id_Ship IS NOT NULL THEN 'Bill'
ELSE '' END
FROM Address as Adr
LEFT JOIN Site ship ON ship.Ship_Address_id = Adr.id
LEFT JOIN Site bill ON bill.Bill_Address_id = Adr.id
即使我不使用 CASE,它也不会为站点的每个地址获取两行。
请指教。
编辑 这是所需的输出 table: 与站点 table 一样,我们有两个不同的地址 ID table (Ship/Bill) 因此结果 table 应该为每个 site.id[=29= 显示两行] 例如,我正在获取 site.id 1 和 3 的记录,然后
Result_Table:
| Address.ID | Address Details | TYPE | ... |
--------------------------------------------
| 1 | Other Details | Ship | ... |
| 2 | Other Details | Bill | ... |
| 4 | Other Details | Ship | ... |
| 4 | Other Details | Bill | ... |
有多种方法可以做到这一点。这是我用UNPIVOT实现的一个例子,大家可以参考一下:
declare @address table(id int, details nvarchar(100))
declare @site table(id int, details nvarchar(100), ship_address_id int, bill_address_id int)
insert into @address values(1,'details 1')
insert into @address values(2,'details 2')
insert into @address values(3,'details 3')
insert into @address values(4,'details 4')
insert into @site values(1,'details 1',1,2)
insert into @site values(2,'details 1',1,3)
insert into @site values(3,'details 1',4,4)
insert into @site values(4,'details 1',2,5)
SELECT *
FROM (
SELECT s.id as site_id, s.bill_address_id, s.ship_address_id
FROM @Site AS s
INNER JOIN @Address AS sa ON s.Ship_Address_id = sa.Id
INNER JOIN @Address AS ba ON s.Bill_Address_id = ba.Id
WHERE s.id in (1,3)) p
UNPIVOT
(address_id FOR address_type IN
(Ship_Address_id, Bill_Address_id)
) AS unpvt
输出
site_id address_id address_type
1 1 ship_address_id
1 2 bill_address_id
3 4 ship_address_id
3 4 bill_address_id
您似乎在寻找 UNION ALL
,而且您的表格是倒着的。我认为您正在寻找更像这样的东西:
SELECT ship.id Site_id, CASE
WHEN ship.CRM_Address_Internal_Id_Ship IS NOT NULL THEN 'Ship'
ELSE 'No Ship' END AddressPresent
FROM Site ship
LEFT JOIN Address Adr ON ship.Ship_Address_id = Adr.id
UNION ALL
SELECT bill.id Site_id, CASE
WHEN bill.CRM_Address_Internal_Id_Ship IS NOT NULL THEN 'Bill'
ELSE 'No Bill' END AddressPresent
FROM Site bill
LEFT JOIN Address Adr ON bill.Bill_Address_id = Adr.id
我还想知道您是否有 'CRM_Address_Internal_Id_Bill' 列应该在查询的第二部分?