gpt4 book ai didi

mysql - 如何在 MySQL 中选择重复行的第一行(但重复数据位于不同的列中)

转载 作者:行者123 更新时间:2023-11-29 07:23:51 25 4
gpt4 key购买 nike

这是“查找重复行中的第一个”问题的一个变体,但是对于使用常识的人类来说,这些行显然是重复的,但不是 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 时,我将“第一个”定义为序列中较早的位置)。

理想情况下,我想要两个查询,一个返回两个反向对中的第一个,一个返回最后一个,这样无论我们是否认为“名称”是成员或其共同成员(见下文)。

期望的结果

查询1个结果(使用第一个联合出现)

TABLE 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的结果(使用最后一次联合出现)

TABLE 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com