SQL 比较多个行或分区以找到匹配项
SQL compare multiple rows or partitions to find matches
我正在处理的数据库是 DB2,我遇到了类似于以下情况的问题:
Table Structure
-------------------------------
| Teacher Seating Arrangement |
-------------------------------
| PK | seat_argmt_id |
| | teacher_id |
-------------------------------
-----------------------------
| Seating Arrangement |
-----------------------------
|PK FK | seat_argmt_id |
|PK | Row_num |
|PK | seat_num |
|PK | child_name |
-----------------------------
Table Data
------------------------------
| Teacher Seating Arrangement|
------------------------------
| seat_argmt_id | teacher_id |
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
| 5 | 2 |
------------------------------
---------------------------------------------------
| Seating Arrangement |
---------------------------------------------------
| seat_argmt_id | row_num | seat_num | child_name |
| 1 | 1 | 1 | Abe |
| 1 | 1 | 2 | Bob |
| 1 | 1 | 3 | Cat |
| | | | |
| 2 | 1 | 1 | Abe |
| 2 | 1 | 2 | Bob |
| 2 | 1 | 3 | Cat |
| | | | |
| 3 | 1 | 1 | Abe |
| 3 | 1 | 2 | Cat |
| 3 | 1 | 3 | Bob |
| | | | |
| 4 | 1 | 1 | Abe |
| 4 | 1 | 2 | Bob |
| 4 | 1 | 3 | Cat |
| 4 | 2 | 2 | Dan |
---------------------------------------------------
我想看看哪里有重复的老师座位安排。重复是指 row_num
、seat_num
和 child_name
在不同的 seat_argmt_id
中相同的地方 teacher_id
。因此,根据上面提供的数据,只有座位 ID 1 和 2 是我想要撤回的,因为它们在除 seat id
之外的所有内容上都是重复的。如果第 2 个 table 上的所有 children 都是准确的(没有主键和外键,在这种情况下是 seat_argmt_id
),我想看看。
我最初的想法是做一个 count(*) group by row#, seat#, and child
。所有计数 > 1 的东西都意味着它是一个骗局,而 = 1 意味着它是独一无二的。不过,该逻辑仅在您比较单行时才有效。我需要比较多行。我无法通过 SQL 找出一种方法来做到这一点。我的解决方案涉及到 SQL 之外并且有效(可能)。我只是想知道在 DB2 中是否有办法做到这一点。
这是你想要的吗?
select d.teacher_id, sa.row_num, sa.seat_num, sa.child_name
from seatingarrangement sa join
data d
on sa.seat_argmt_id = d.seat_argmt_id
group by d.teacher_id, sa.row_num, sa.seat_num, sa.child_name
having count(*) > 1;
编辑:
如果你想找到两个相同的排列:
select sa1.seat_argmt_id, sa2.seat_argmt_id
from seatingarrangement sa1 join
seatingarrangement sa2
on sa1.seat_argmt_id < sa2.seat_argmt_id and
sa1.row_num = sa2.row_num and
sa1.seat_num = sa2.seat_num and
sa1.child_name = sa2.child_name
group by sa1.seat_argmt_id, sa2.seat_argmt_id
having count(*) = (select count(*) from seatingarrangement sa where sa.seat_argmt_id = sa1.seat_argmt_id) and
count(*) = (select count(*) from seatingarrangement sa where sa.seat_argmt_id = sa2.seat_argmt_id);
这会找到两个排列之间的匹配项,然后验证计数是否正确。
我正在处理的数据库是 DB2,我遇到了类似于以下情况的问题:
Table Structure ------------------------------- | Teacher Seating Arrangement | ------------------------------- | PK | seat_argmt_id | | | teacher_id | ------------------------------- ----------------------------- | Seating Arrangement | ----------------------------- |PK FK | seat_argmt_id | |PK | Row_num | |PK | seat_num | |PK | child_name | ----------------------------- Table Data ------------------------------ | Teacher Seating Arrangement| ------------------------------ | seat_argmt_id | teacher_id | | 1 | 1 | | 2 | 1 | | 3 | 1 | | 4 | 1 | | 5 | 2 | ------------------------------ --------------------------------------------------- | Seating Arrangement | --------------------------------------------------- | seat_argmt_id | row_num | seat_num | child_name | | 1 | 1 | 1 | Abe | | 1 | 1 | 2 | Bob | | 1 | 1 | 3 | Cat | | | | | | | 2 | 1 | 1 | Abe | | 2 | 1 | 2 | Bob | | 2 | 1 | 3 | Cat | | | | | | | 3 | 1 | 1 | Abe | | 3 | 1 | 2 | Cat | | 3 | 1 | 3 | Bob | | | | | | | 4 | 1 | 1 | Abe | | 4 | 1 | 2 | Bob | | 4 | 1 | 3 | Cat | | 4 | 2 | 2 | Dan | ---------------------------------------------------
我想看看哪里有重复的老师座位安排。重复是指 row_num
、seat_num
和 child_name
在不同的 seat_argmt_id
中相同的地方 teacher_id
。因此,根据上面提供的数据,只有座位 ID 1 和 2 是我想要撤回的,因为它们在除 seat id
之外的所有内容上都是重复的。如果第 2 个 table 上的所有 children 都是准确的(没有主键和外键,在这种情况下是 seat_argmt_id
),我想看看。
我最初的想法是做一个 count(*) group by row#, seat#, and child
。所有计数 > 1 的东西都意味着它是一个骗局,而 = 1 意味着它是独一无二的。不过,该逻辑仅在您比较单行时才有效。我需要比较多行。我无法通过 SQL 找出一种方法来做到这一点。我的解决方案涉及到 SQL 之外并且有效(可能)。我只是想知道在 DB2 中是否有办法做到这一点。
这是你想要的吗?
select d.teacher_id, sa.row_num, sa.seat_num, sa.child_name
from seatingarrangement sa join
data d
on sa.seat_argmt_id = d.seat_argmt_id
group by d.teacher_id, sa.row_num, sa.seat_num, sa.child_name
having count(*) > 1;
编辑:
如果你想找到两个相同的排列:
select sa1.seat_argmt_id, sa2.seat_argmt_id
from seatingarrangement sa1 join
seatingarrangement sa2
on sa1.seat_argmt_id < sa2.seat_argmt_id and
sa1.row_num = sa2.row_num and
sa1.seat_num = sa2.seat_num and
sa1.child_name = sa2.child_name
group by sa1.seat_argmt_id, sa2.seat_argmt_id
having count(*) = (select count(*) from seatingarrangement sa where sa.seat_argmt_id = sa1.seat_argmt_id) and
count(*) = (select count(*) from seatingarrangement sa where sa.seat_argmt_id = sa2.seat_argmt_id);
这会找到两个排列之间的匹配项,然后验证计数是否正确。