2

有一个具有相似架构的表

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
4

3 回答 3

1

根据订单的准确程度,您可以执行以下操作。

这是获取带有计数的所有唯一控件/代码/数量,以获取一个标志以了解这是否是重复行,并按控件/代码/数量排序,以便它们按顺序排列。它进行交叉连接以初始化一些用户变量。

然后它计算一个计数器,只有在任何控制/代码/数量发生变化并且它是重复行时才增加它。然后设置用户变量来存储之前的控制/代码/数量值。

然后,外部查询将结果重新排序为 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 JOIN 将其返回到主表,以将该序列号放入所有匹配的行中。

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
于 2016-01-12T13:17:53.333 回答
1

这似乎是比@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;
于 2016-01-12T13:27:26.980 回答
-1

你需要一个 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

如果要求列出包括所选记录的重复项,您可以很好地省略最后一个不等于。

于 2016-01-12T12:41:18.903 回答