MySQL table 上的重复记录数
Number duplicate records on the MySQL table
有一个 table 具有相似架构
id control code amount
1 200 12 300
2 400 12 300
3 200 12 300
4 100 10 400
5 100 10 400
6 500 13 500
正在尝试列出 UI 上的重复记录。
使用以下查询,我可以检索重复记录并将其显示在 UI。
select * from mwt group by control,code,amount having count(id) > 1;
id control code amount
1 200 12 300
4 100 10 400
这里id为1和4的记录分别是3和5的副本。
在 UI 上,用户将单击记录旁边的复选框,相应的重复记录应填充到 UI。为了使事情更容易尝试填充另一个名为 dup_id 的列。使用此 dup_id 可以过滤 UI 的结果,格式为 JSON。
如何创建类似于下图的结果集?
id control code amount dup_id
1 200 12 300 1
2 400 12 300
3 200 12 300 1
4 100 10 400 4
5 100 10 400 4
6 500 13 500
您需要 dup_id 专栏吗?。我希望这可以通过如下所示的简单查询来实现
select id
, control
, code
, amount
from table
where control = from selected Record
and code = from selected Record
and amount = from selected Record
and id not equals from selected Record
如果要求列出包括所选记录在内的重复项,您可以很好地省略最后一个不等于。
根据订单的准确性,您可以这样做。
这是获取所有具有计数的唯一控件/代码/数量,以获取标志以了解该行是否重复,并按控件/代码/数量排序,以便它们按顺序排列。它进行交叉连接以初始化一些用户变量。
然后它计算一个计数器,只有在任何控制/代码/数量发生变化并且它是重复的行时才递增它。然后设置用户变量来存储控件/代码/金额的先前值。
外部查询然后将结果按 id 顺序排序。
SELECT sub3.id,
sub3.control,
sub3.code,
sub3.amount,
sub3.dup_id
FROM
(
SELECT sub2.id,
sub2.control,
sub2.code,
sub2.amount,
@cnt:=IF(@control=control AND @code=code AND @amount=amount AND sub2.id_count IS NOT NULL, @cnt, IF(sub2.id_count IS NULL, @cnt, @cnt + 1)),
@control:=control,
@code:=code,
@amount:=amount,
IF(sub2.id_count IS NULL, NULL, @cnt) AS dup_id
FROM
(
SELECT mwt.id, mwt.control, mwt.code, mwt.amount, sub1.id_count
FROM mwt
LEFT OUTER JOIN
(
SELECT control, code, amount, COUNT(id) AS id_count
FROM mwt
GROUP BY control,code,amount
HAVING id_count > 1
) sub1
ON mwt.control = sub1.control
AND mwt.code = sub1.code
AND mwt.amount = sub1.amount
ORDER BY mwt.control, mwt.code, mwt.amount
) sub2
CROSS JOIN
(
SELECT @cnt:=0, @control:=0, @code:=0, @amount:=0
) sub0
) sub3
ORDER BY id
请注意,这是按控件、代码和数量排序的,因此与您所需的输出不完全匹配(这需要首先按 ID 排序的第一个副本)。
编辑 - 更简单更好的方法。这将获取所有具有这些重复项的最小 ID 的重复行(按最小 ID 排序),并使用用户变量为这些重复项添加序列号。然后 LEFT OUTER JOINs 返回主 table 以将该序列号放入所有匹配的行中。
SELECT mwt.id, mwt.control, mwt.code, mwt.amount, sub2.dup_id
FROM mwt
LEFT OUTER JOIN
(
SELECT sub1.id, sub1.control, sub1.code, sub1.amount, @cnt:=@cnt+1 AS dup_id
FROM
(
SELECT MIN(id) AS id, control, code, amount
FROM mwt
GROUP BY control,code,amount
HAVING COUNT(id) > 1
ORDER BY id
) sub1
CROSS JOIN
(
SELECT @cnt:=0
) sub0
) sub2
ON mwt.control = sub2.control
AND mwt.code = sub2.code
AND mwt.amount = sub2.amount
ORDER BY mwt.id
这似乎比@kickstarter 建议的解决方案更简单 - 但也许我误解了要求...
SELECT x.*
, y.dup_id
FROM my_table x
LEFT
JOIN
( SELECT MIN(id) dup_id
, control
, code
, amount
FROM my_table
GROUP
BY control
, code
, amount
HAVING COUNT(*) > 1
) y
ON y.control = x.control
AND y.code = x.code
AND y.amount = x.amount;
有一个 table 具有相似架构
id control code amount
1 200 12 300
2 400 12 300
3 200 12 300
4 100 10 400
5 100 10 400
6 500 13 500
正在尝试列出 UI 上的重复记录。
使用以下查询,我可以检索重复记录并将其显示在 UI。
select * from mwt group by control,code,amount having count(id) > 1;
id control code amount
1 200 12 300
4 100 10 400
这里id为1和4的记录分别是3和5的副本。
在 UI 上,用户将单击记录旁边的复选框,相应的重复记录应填充到 UI。为了使事情更容易尝试填充另一个名为 dup_id 的列。使用此 dup_id 可以过滤 UI 的结果,格式为 JSON。
如何创建类似于下图的结果集?
id control code amount dup_id
1 200 12 300 1
2 400 12 300
3 200 12 300 1
4 100 10 400 4
5 100 10 400 4
6 500 13 500
您需要 dup_id 专栏吗?。我希望这可以通过如下所示的简单查询来实现
select id
, control
, code
, amount
from table
where control = from selected Record
and code = from selected Record
and amount = from selected Record
and id not equals from selected Record
如果要求列出包括所选记录在内的重复项,您可以很好地省略最后一个不等于。
根据订单的准确性,您可以这样做。
这是获取所有具有计数的唯一控件/代码/数量,以获取标志以了解该行是否重复,并按控件/代码/数量排序,以便它们按顺序排列。它进行交叉连接以初始化一些用户变量。
然后它计算一个计数器,只有在任何控制/代码/数量发生变化并且它是重复的行时才递增它。然后设置用户变量来存储控件/代码/金额的先前值。
外部查询然后将结果按 id 顺序排序。
SELECT sub3.id,
sub3.control,
sub3.code,
sub3.amount,
sub3.dup_id
FROM
(
SELECT sub2.id,
sub2.control,
sub2.code,
sub2.amount,
@cnt:=IF(@control=control AND @code=code AND @amount=amount AND sub2.id_count IS NOT NULL, @cnt, IF(sub2.id_count IS NULL, @cnt, @cnt + 1)),
@control:=control,
@code:=code,
@amount:=amount,
IF(sub2.id_count IS NULL, NULL, @cnt) AS dup_id
FROM
(
SELECT mwt.id, mwt.control, mwt.code, mwt.amount, sub1.id_count
FROM mwt
LEFT OUTER JOIN
(
SELECT control, code, amount, COUNT(id) AS id_count
FROM mwt
GROUP BY control,code,amount
HAVING id_count > 1
) sub1
ON mwt.control = sub1.control
AND mwt.code = sub1.code
AND mwt.amount = sub1.amount
ORDER BY mwt.control, mwt.code, mwt.amount
) sub2
CROSS JOIN
(
SELECT @cnt:=0, @control:=0, @code:=0, @amount:=0
) sub0
) sub3
ORDER BY id
请注意,这是按控件、代码和数量排序的,因此与您所需的输出不完全匹配(这需要首先按 ID 排序的第一个副本)。
编辑 - 更简单更好的方法。这将获取所有具有这些重复项的最小 ID 的重复行(按最小 ID 排序),并使用用户变量为这些重复项添加序列号。然后 LEFT OUTER JOINs 返回主 table 以将该序列号放入所有匹配的行中。
SELECT mwt.id, mwt.control, mwt.code, mwt.amount, sub2.dup_id
FROM mwt
LEFT OUTER JOIN
(
SELECT sub1.id, sub1.control, sub1.code, sub1.amount, @cnt:=@cnt+1 AS dup_id
FROM
(
SELECT MIN(id) AS id, control, code, amount
FROM mwt
GROUP BY control,code,amount
HAVING COUNT(id) > 1
ORDER BY id
) sub1
CROSS JOIN
(
SELECT @cnt:=0
) sub0
) sub2
ON mwt.control = sub2.control
AND mwt.code = sub2.code
AND mwt.amount = sub2.amount
ORDER BY mwt.id
这似乎比@kickstarter 建议的解决方案更简单 - 但也许我误解了要求...
SELECT x.*
, y.dup_id
FROM my_table x
LEFT
JOIN
( SELECT MIN(id) dup_id
, control
, code
, amount
FROM my_table
GROUP
BY control
, code
, amount
HAVING COUNT(*) > 1
) y
ON y.control = x.control
AND y.code = x.code
AND y.amount = x.amount;