我正在使用的数据库具有三个具有相同列布局的表,即OPEX,NOPEX和CAPEX。我想查询所有三个具有匹配AssetId
的项目,并获得一个结果集,以便我可以在自己的.Net代码中同时处理它们。
我需要知道他们来自哪张桌子。
我知道我可以使用SELECT子句中的一系列CASE做到这一点,也许使用每个非零的ID列来确定它来自哪个表。但是我必须为每一列设置一个,并且表非常宽。
还有其他解决方法吗?
答案 0 :(得分:3)
为了将它们分成一组,可以结合使用UNION和EXISTS()检查。 UNION ALL将为您提供一个包含所有三个表中数据的单个结果集,对每个表进行EXISTS检查将确认您要查询的表在其他表中具有相应的记录。
SELECT *, 'OPEX' AS table_name
FROM OPEX o
WHERE EXISTS (
SELECT 1
FROM NOPEX n
WHERE n.asset_id = o.asset_id)
AND EXISTS (
SELECT 1
FROM CAPEX c
WHERE c.asset_id = o.asset_id)
UNION ALL
SELECT *, 'NOPEX' AS table_name
FROM NOPEX n
WHERE EXISTS (
SELECT 1
FROM Opex o
WHERE o.asset_id = n.asset_id)
AND EXISTS (
SELECT 1
FROM CAPEX c
WHERE c.asset_id = n.asset_id)
UNION ALL
SELECT *, 'CAPEX' AS table_name
FROM CAPEX c
WHERE EXISTS (
SELECT 1
FROM Opex o
WHERE o.asset_id = c.asset_id)
AND EXISTS (
SELECT 1
FROM NOPEX n
WHERE n.asset_id = c.asset_id)
我想您也可以进行内部联接?
SELECT c.*, 'CAPEX' AS table_name
FROM CAPEX c
INNER JOIN OPEX o
ON o.asset_id = c.asset_id
INNER JOIN NOPEX n
ON n.asset_id = c.asset_id
UNION ALL
SELECT o.*, 'OPEX' AS table_name
FROM OPEX o
INNER JOIN CAPEX c
ON c.asset_id = o.asset_id
INNER JOIN NOPEX n
ON n.asset_id = o.asset_id
UNION ALL
SELECT n.*, 'NOPEX' AS table_name
FROM NOPEX n
INNER JOIN OPEX o
ON o.asset_id = n.asset_id
INNER JOIN CAPEX c
ON c.asset_id = n.asset_id
答案 1 :(得分:0)
对dfundako的回答类似,但是要更快地解决所有三个表中AssetId
的位置,而对相关表的索引的命中要少:
;with cte as (
select
AssetID
from (
select distinct
AssetID
from Opex
union all
select distinct
AssetID
from Nopex
union all
select distinct
AssetID
from Capex
) as AssetIDs
group by AssetId
having count(AssetId) = 3
)
select 'Opex', * from Opex as o
inner join cte
on o.AssetID = cte.AssetID
union all
select 'Nopex', * from Nopex as n
inner join cte
on n.AssetID = cte.AssetID
union all
select 'Capex', * from Capex as c
inner join cte
on c.AssetID = cte.AssetID