我有一个令人困惑的逻辑。我有一个表person_details
,它有一个唯一的主键id
和外键persid
。另一个外键是common_id
。 common_id
基于1和2.如果为1,则表示asset
。如果为2,则表示liability
。
person_details
表:
| id | details |persid | common_id |
|_____|__________________|_______|____________|
200 asset details 30 1
201 asset details2 30 1
203 liability detail 30 2
我希望将资产和责任详细信息分开并返回单个连接查询。当我尝试一个简单的查询时,它会返回重复的责任条目。
select a.details assetdet,
b.details liabdetails,
a.common_id assetid,
b.common_id liabId
from person_details a
join person_details b
on a.persid = b.persid
where a.common_id = 1 and
b.common_id = 2 and
a.persid = 30
现在它返回:
| assetdet | liabdetails | assetid | liabId |
|_______________|_________________|____________|__________|
asset details liability detail 1 2
asset details2 liability detail 1 2
我想返回
| assetdet | liabdetails | assetid | liabId |
|_______________|_________________|____________|__________|
asset details liability detail 1 2
asset details2 null 1 null
答案 0 :(得分:0)
您似乎只想加入一组资产的第一行,其中第一行来自一组负债。如果是这样,那么一个选项是使用CTE并为两个组的每个记录分配行号。然后在连接条件中使用此选项以确保只有资产/负债的第一条记录匹配。
WITH cte AS (
SELECT id, details, persid, common_id,
ROW_NUMBER() OVER (PARTITION BY common_id ORDER BY id) rn
FROM person_details
)
SELECT a.details assetdet,
b.details liabdetails,
a.common_id assetid,
b.common_id liabId
FROM cte a
LEFT JOIN cte b
ON a.persid = b.persid AND
a.rn = 1 AND
b.rn = 1 AND
b.common_id = 2 AND
a.persid = 30
WHERE a.common_id = 1;
<强>输出:强>
答案 1 :(得分:0)
在某种程度上,这似乎是一个建模问题:person_details
感觉它应该是两个表。无论如何,此解决方案使用子查询工厂将表拆分为两个结果集并使用左外连接。这样可以防止重复责任记录。
with asst as (
select id
, details
, persid
, row_number() over (order by id) rn
from person_details
where common_id = 1
)
, liab as (
select id
, details
, persid
, row_number() over (order by id) rn
from person_details
where common_id = 2
)
select asst.details as asset_details
, liab.details as liability_details
, asst.common_id as asset_id
, liab.common_id as liability_id
from asst
left outer join liab
on asst.persid = liab.persid
and asst.rn = liab.rn
where asst.persid = 30
/
此解决方案解决了您发布的数据的问题。如果遗产记录多于资产记录,则无效。在这种情况下,您需要一个完整的外部联接。