这是我一直试图解决的SQL问题,但我没有
到目前为止能够解决:

假设我有一张桌子:

序列(1号整数,2号整数,3号整数,4号整数,5号整数)

如果序列中存在一行,例如:

那么我想消除作为该排列的其他每一行,
例如该行:


编辑:
主键是(数字1,数字2,数字3,数字4,数字5)

最佳答案

假设无法在五列中重复这些值,并且该表只有一列primary_key-

DELETE t2
FROM table t1
INNER JOIN table t2
    ON (t1.col1 IN (t2.col1, t2.col2, t2.col3, t2.col4, t2.col5)
        AND t1.col2 IN (t2.col1, t2.col2, t2.col3, t2.col4, t2.col5)
        AND t1.col3 IN (t2.col1, t2.col2, t2.col3, t2.col4, t2.col5)
        AND t1.col4 IN (t2.col1, t2.col2, t2.col3, t2.col4, t2.col5)
        AND t1.col5 IN (t2.col1, t2.col2, t2.col3, t2.col4, t2.col5)
    )
    AND t1.primary_key < t2.primary_key
    -- AND CONCAT(t1.col1, t1.col2, t1.col3, t1.col4, t1.col5) < CONCAT(t2.col1, t2.col2, t2.col3, t2.col4, t2.col5)
WHERE t1.col1 NOT IN (t1.col2, t1.col3, t1.col4, t1.col5)
AND t1.col2 NOT IN (t1.col3, t1.col4, t1.col5)
AND t1.col3 NOT IN (t1.col4, t1.col5)
AND t1.col4 <> t1.col5


我还没有尝试过,因此建议您在提交给DELETE之前,将其作为SELECT运行。

更新以下查询将适用于集合中存在重复值的情况(1、2、3、2、5,而不是1、2、3、4、5),但是连接非常昂贵,所以我会在非常大的数据集上运行时非常谨慎。

DELETE t2
FROM `table` t1
INNER JOIN `table` t2
    ON (    t1.col1 IN (t2.col1, t2.col2, t2.col3, t2.col4, t2.col5)
        AND t1.col2 IN (t2.col1, t2.col2, t2.col3, t2.col4, t2.col5)
        AND t1.col3 IN (t2.col1, t2.col2, t2.col3, t2.col4, t2.col5)
        AND t1.col4 IN (t2.col1, t2.col2, t2.col3, t2.col4, t2.col5)
        AND t1.col5 IN (t2.col1, t2.col2, t2.col3, t2.col4, t2.col5)
    )
    AND (-- compare the number of occurrences of each value in each side
            (IF(t1.col1=t1.col1, 1, 0)+IF(t1.col1=t1.col2, 1, 0)+IF(t1.col1=t1.col3, 1, 0)+IF(t1.col1=t1.col4, 1, 0)+IF(t1.col1=t1.col5, 1, 0)) = (IF(t1.col1=t2.col1, 1, 0)+IF(t1.col1=t2.col2, 1, 0)+IF(t1.col1=t2.col3, 1, 0)+IF(t1.col1=t2.col4, 1, 0)+IF(t1.col1=t2.col5, 1, 0))
        AND (IF(t1.col2=t1.col1, 1, 0)+IF(t1.col2=t1.col2, 1, 0)+IF(t1.col2=t1.col3, 1, 0)+IF(t1.col2=t1.col4, 1, 0)+IF(t1.col2=t1.col5, 1, 0)) = (IF(t1.col2=t2.col1, 1, 0)+IF(t1.col2=t2.col2, 1, 0)+IF(t1.col2=t2.col3, 1, 0)+IF(t1.col2=t2.col4, 1, 0)+IF(t1.col2=t2.col5, 1, 0))
        AND (IF(t1.col3=t1.col1, 1, 0)+IF(t1.col3=t1.col2, 1, 0)+IF(t1.col3=t1.col3, 1, 0)+IF(t1.col3=t1.col4, 1, 0)+IF(t1.col3=t1.col5, 1, 0)) = (IF(t1.col3=t2.col1, 1, 0)+IF(t1.col3=t2.col2, 1, 0)+IF(t1.col3=t2.col3, 1, 0)+IF(t1.col3=t2.col4, 1, 0)+IF(t1.col3=t2.col5, 1, 0))
        AND (IF(t1.col4=t1.col1, 1, 0)+IF(t1.col4=t1.col2, 1, 0)+IF(t1.col4=t1.col3, 1, 0)+IF(t1.col4=t1.col4, 1, 0)+IF(t1.col4=t1.col5, 1, 0)) = (IF(t1.col4=t2.col1, 1, 0)+IF(t1.col4=t2.col2, 1, 0)+IF(t1.col4=t2.col3, 1, 0)+IF(t1.col4=t2.col4, 1, 0)+IF(t1.col4=t2.col5, 1, 0))
        AND (IF(t1.col5=t1.col1, 1, 0)+IF(t1.col5=t1.col2, 1, 0)+IF(t1.col5=t1.col3, 1, 0)+IF(t1.col5=t1.col4, 1, 0)+IF(t1.col5=t1.col5, 1, 0)) = (IF(t1.col5=t2.col1, 1, 0)+IF(t1.col5=t2.col2, 1, 0)+IF(t1.col5=t2.col3, 1, 0)+IF(t1.col5=t2.col4, 1, 0)+IF(t1.col5=t2.col5, 1, 0))
    )
    AND t1.primary_key < t2.primary_key
    -- AND CONCAT(t1.col1, t1.col2, t1.col3, t1.col4, t1.col5) < CONCAT(t2.col1, t2.col2, t2.col3, t2.col4, t2.col5)


如果表没有单列主键,则可以使用注释掉的比较而不是PK,但是PK绝对是首选。

关于mysql - 从表中消除排列,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9651498/

10-13 02:53