鉴于下表(people_table
):
PersonId CoupleId
-------------------
1 2
2 1
3 (null)
4 5
5 4
通过编写类似于此的查询
Select count(?) from people_table
我希望2作为计数结果
我认为最简单的方法是:
select count(*)
from people_table
where PersonId < CoupleId ;
为什么这样做?好吧,一对夫妇中的两个人有不同的ID。其中一个必须比另一个小,这就算其中一个。
这也过滤掉了NULL
值。
注意:这假设您的数据格式正确 - 也就是说,一对夫妇中的两个人都在表中作为单独的行。
select count(*) from table
where personID in (select coupleID from table)
and coupleID in (select personid from table)
and coupleID > personID
希望能帮助到你!
逻辑
- 使用内连接+连接表的PersonId =你的表的CoupleId和连接表的CoupleId =你的表的PersonId
- 因为内连接将获得双行,所以它必须得到
count(1) / 2
计数。
架构(Oracle v11g)
CREATE TABLE T
("PersonId" int, "CoupleId" int)
INSERT ALL
INTO T ("PersonId", "CoupleId")
VALUES (1, 2)
INTO T ("PersonId", "CoupleId")
VALUES (2, 1)
INTO T ("PersonId", "CoupleId")
VALUES (3, null)
INTO T ("PersonId", "CoupleId")
VALUES (4, 5)
INTO T ("PersonId", "CoupleId")
VALUES (5, 4)
SELECT * FROM dual
不允许使用PersonId和CoupleId重复版本
select count(1) / 2 cnt from T T1
inner join T T2 on T1."PersonId" = T2."CoupleId" and T1."CoupleId" = T2."PersonId"
cnt
---
2
允许PersonId和CoupleId重复版本
with cte as (
select distinct * from T
)
select count(1) / 2 cnt from CTE T1
inner join CTE T2 on T1."PersonId" = T2."CoupleId" and T1."CoupleId" = T2."PersonId"
cnt
---
2
你可以将least()
和greatest()
函数应用于personid
和coupleid
和group by
他们,最后计算行数:
select count(*) counter from (
select least(personId, coupleId), greatest(personId, coupleId)
from people_table
where personId is not null and coupleId is not null
group by least(personId, coupleId), greatest(personId, coupleId)
)
见demo
下面是使用连接的查询 -
with table1 as (
select 1 as PersonId , 2 as CoupleId from dual
union
select 2 as PersonId , 1 as CoupleId from dual
union
select 3 as PersonId , null as CoupleId from dual
union
select 4 as PersonId , 5 as CoupleId from dual
union
select 5 as PersonId , 4 as CoupleId from dual)
select count(*) from table1 t1 inner join table1 t2 on t1.personId=t2.coupleid and t1.coupleId=t2.personId
where t1.personId>t1.coupleId;
您可以“规范化”列以先获得较低的值,然后应用distinct来删除重复项:
SELECT Count(*)
FROM
(
SELECT DISTINCT Least(PersonID, CoupleID) AS a, Greatest(PersonID, CoupleID) AS b
FROM nodupes
WHERE PersonID IS NOT NULL
AND CoupleID IS NOT NULL
) dt
首先,在PersonId和CoupleId列中计算具有相同值的对,然后删除所有小于2的行,然后计算结果集中的行。
with
table1 as (
select 1 as PersonId, 2 as CoupleId from dual union all
select 2, 1 from dual union all select 3, null from dual union all
select 4, 5 from dual union all select 5, 4 from dual union all
select 4, 5 from dual union all select 2, 1 from dual
)
select count(*) as qnt
from (
select count(*) as qnt
from table1
group by case when PersonId < CoupleId then PersonId else CoupleId end,
case when PersonId < CoupleId then CoupleId else PersonId end
having count(*) > 1
);
输出:
QNT
----------
2
使用db<>fiddle在线测试。