这是“查找第一个重复行”问题的变体,但是对于人类来说,使用常识显然是重复的行,但不是 MySQL 定义的重复行。
下表显示了组织成员应付款。 每行保存成员数据,如果它们的伙伴也是联合成员,则它们的联合数据相同,否则这些列为空或空字符串。 该表当前按member_name、member_ID 排序。
所有成员都出现在成员列中,因此,如果成员/联合元组出现在一行中,它最终会在其他地方“重复”出现,但成员和联合字段相反。
具体出现的位置取决于关节名称的字母顺序。
该表源自其他地方用于其他目的,因此当我获得它时我无法控制它的结构。例如
表 payment_due :
member_id | member_name | member_payment | joint_id | joint_name | joint_payment
==========|=============|================|==========|============|=============
11 | ARNOLD | 40 | (NULL) | | (NULL)
22 | BAKER | 36 | 88 | ELNET | 35
33 | COOPER | 30 | 44 | COOPER | 30
44 | COOPER | 30 | 33 | COOPER | 30
55 | DAVIS | 40 | (NULL) | | (NULL)
88 | ELNET | 35 | 22 | BAKER | 36
66 | FRENCH | 37 | 99 | JOYCE | 50
77 | GRANT | 45 | (NULL) | | (NULL)
99 | JOYCE | 50 | 66 | FRENCH | 37
100 | LAWSON | 46 | (NULL) | | (NULL)
请有人帮助我设计一个查询,该查询将显示包含非联合成员的所有行以及联合关系的第一行,即不显示重复/反转的行。
(当原始表应用了 ORDER BY member_name, member_ID 时,我将“first”定义为序列中较早的位置)。
理想情况下,我想要两个查询,一个返回两个反向对中的第一个,一个返回最后一个,以便可以按成员名称的字母顺序生成报告,无论我们是否认为“名称”是该成员的名称。成员或其联合成员(见下文)。
期望的结果
查询 1 结果(使用第一个联合出现)
表 payment_due
member_id | member_name | member_payment | joint_id | joint_name | joint_payment
==========|=============|================|==========|============|=============
11 | ARNOLD | 40 | (NULL) | | (NULL)
22 | BAKER | 36 | 88 | ELNET | 35
33 | COOPER | 30 | 44 | COOPER | 30
55 | DAVIS | 40 | (NULL) | | (NULL)
66 | FRENCH | 37 | 100 | JOYCE | 50
77 | GRANT | 45 | (NULL) | | (NULL)
100 | LAWSON | 46 | (NULL) | | (NULL)
(ie member_id's 44, 88, 100 not shown)
或查询 2 结果(使用最后一次联合出现)
表 payment_due
member_id | member_name | member_payment | joint_id | joint_name | joint_payment
==========|=============|================|==========|============|=============
11 | ARNOLD | 40 | (NULL) | | (NULL)
44 | COOPER | 30 | 33 | COOPER | 30
55 | DAVIS | 40 | (NULL) | | (NULL)
88 | ELNET | 35 | 22 | BAKER | 36
77 | GRANT | 45 | (NULL) | | (NULL)
99 | JOYCE | 50 | 66 | FRENCH | 37
100 | LAWSON | 46 | (NULL) | | (NULL)
(ie member_id's 22, 33, 66 not shown)
我尝试过的
我尝试过添加增量列并进行非关节的联合和通常的“重复行的第一个”SQL 结构,但我不知道如何在数据被复制时将反转行定义为“重复”出现在不同的列中(代码如下)。
这里有一个db-fiddle https://www.db-fiddle.com/f/f7DoySyi8boDG3DxMpcD86/0
(我使用 DB-Fiddle 因为 SQLfiddle 目前似乎有问题,至少对我来说)
已尝试代码
-- make a temp table with an extra column holding a unique identifier 'orderby'
SET @x:=0;
CREATE TEMPORARY TABLE payment_due_2 AS
(SELECT
@x:=@x+1 AS orderby,
payment_due.*
FROM payment_due);
-- make a copy of the temp table to avoid problems with reopening temp tables
CREATE TEMPORARY TABLE payment_due_3 AS
(SELECT * FROM payment_due_2);
-- make a second copy of the temp table for the same reason
CREATE TEMPORARY TABLE payment_due_4 AS
(SELECT * FROM payment_due_2);
SELECT * FROM
(
SELECT payment_due_4.* -- get all the non joints
FROM payment_due_4
WHERE joint_id IS NULL
UNION
SELECT payment_due_2.* -- get the first of the 'duplicates'
FROM payment_due_2
JOIN
(SELECT MIN(orderby) AS min_id
FROM payment_due_3
GROUP BY payment_due_3.member_id
) AS T3
ON payment_due_2.orderby = T3.min_id
) as T5
ORDER BY member_name, member_id;
我查看了this SO question这似乎是我的重复,但我发现它不是很清楚。这是因为,正如另一位 SO 用户所说,“它指定了两个不同的事情(查找重复项,将标志设置为“Y”)”,并且接受的答案没有解决两个不同列中的重复数据。
最佳答案
我想您应该能够使用具有 EXISTS 条件的相关子查询来过滤掉不需要的重复项。
此查询保留具有最小member_id的重复项(以及没有joint_id的记录):
SELECT *
FROM payment_due p
WHERE NOT EXISTS (
SELECT 1
FROM payment_due p1
WHERE
p1.member_id = p.joint_id
AND p1.joint_id = p.member_id
AND p1.member_id < p.member_id
)
要获取具有最高member_id的重复项,只需更改子查询中的最后一个条件:
AND p1.member_id > p.member_id
关于mysql - 如何在 MySQL 中选择重复行的第一个(但重复数据位于不同列中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54843627/