GROUP BY 已与两个子查询分组的另一个表

Gag*_*ous 7 mysql sql group-by conditional-statements having-clause

我有这样的桌子

Table1

ID      |    Val         |     Val2       |
606541  |3175031503131004|3175032612900004|
606542  |3175031503131004|3175032612900004|
677315  |3175031503131004|3175032612980004|
222222  |1111111111111111|8888888888888888|
231233  |1111111111111111|3175032612900004|
111111  |9999992222211111|1111111111111111|
57      |3173012102121018|3173015101870020|
59      |3173012102121018|3173021107460002|
2       |900             |7000            |
4       |900             |7001            |
Run Code Online (Sandbox Code Playgroud)

我有两个条件列ValVal2。显示结果,如果Val

  1. Val 列至少有两个或多个重复值AND
  2. Val2 列没有重复值(唯一)

例如 :

示例 1

 ID      |    Val         |     Val2       |
 606541  |3175031503131004|3175032612900004|
 606542  |3175031503131004|3175032612900004|  
 677315  |3175031503131004|3175032612980004|

 False, because  even the Val column 
 had two or more duplicate but the Val2 
 had dulicate value (ID 606541  and 606542)
Run Code Online (Sandbox Code Playgroud)

样本预期 1 结果

 No records
Run Code Online (Sandbox Code Playgroud)

样本 2

 ID      |    Val         |     Val2       |
 222222  |1111111111111111|8888888888888888|
 231233  |1111111111111111|3175032612900004|   
 111111  |9999992222211111|1111111111111111|

 True, Because the condition is match, 
 Val column had duplicate value AND Val2 had unique values
Run Code Online (Sandbox Code Playgroud)

样本 2 预期结果

 ID      |    Val         |     Val2       |
 222222  |1111111111111111|8888888888888888|
 231233  |1111111111111111|3175032612900004|
Run Code Online (Sandbox Code Playgroud)

示例 3

 ID      |    Val         |     Val2       |
 606541  |3175031503131004|3175032612900004|
 606542  |3175031503131004|3175032612900004|
 677315  |3175031503131004|3175032612980004|
 222222  |1111111111111111|8888888888888888|     
 231233  |1111111111111111|3175032612900004|
 111111  |9999992222211111|1111111111111111|

 Note : This is false condition, Because even the value for id 606541, 606542, and
 677315 in column Val had duplicate value at least 
 two or more but the value in column Val2 had no unique value (it could be true condition if id 606541, 
 606542, and 677315 had 3 different value on Val2).

 NOte 2 : for Id 222222 and 231233 that had duplicate value, this is still false, because the column 
 Val2 with ID 231233 had the same value with ID 606542 and 606541 (3175032612900004), so it didnt match 
 the second condition which only have no duplicate value
Run Code Online (Sandbox Code Playgroud)

样本 3 预期结果

 No records
Run Code Online (Sandbox Code Playgroud)

现在回到Table1前面,我试图用这个查询显示两个条件的结果

SELECT
tb.* FROM table1 tb 
WHERE
    tb.Val2 IN (
    SELECT ta.Val2 
    FROM (
        SELECT
            t.* 
        FROM
            table1 t 
        WHERE
            t.Val IN ( 
            SELECT Val FROM table1 
            GROUP BY Val 
            HAVING count( Val ) > 1 ) 
        ) ta 
    GROUP BY
        ta.Val2 
    HAVING
    count( ta.Val2 ) = 1 
    )
Run Code Online (Sandbox Code Playgroud)

结果

ID         Val                   Val2
677315  3175031503131004    3175032612980004
222222  1111111111111111    8888888888888888
57      3173012102121018    3173015101870020
59      3173012102121018    3173021107460002
2       900                  7000            
4       900                  7001 
Run Code Online (Sandbox Code Playgroud)

虽然我希望结果是这样的:

ID         Val                   Val2
57  3173012102121018    3173015101870020
59  3173012102121018    3173021107460002
2       900             7000            
4       900             7001            
Run Code Online (Sandbox Code Playgroud)

我的查询有问题吗?

这是我的数据库小提琴

Har*_*shi 7

你必须使用Group By查找valval2重复的值,并需要使用Inner Join,并Left Join以包含/排除的记录为给定的条件(反对INNOT IN等等,可能导致性能问题的情况下,你处理大量数据的条款)。

请在下面找到查询:

select t1.*from table1 t1 left join
      (select val from table1
       where val2 in (select val2 from table1 group by val2 having count(id) > 1)
        ) t2
 on t1.val = t2.val
 inner join
     (select val from table1 group by val having count(id) >1) t3
     on t1.val = t3.val
 where t2.val is null
Run Code Online (Sandbox Code Playgroud)

查询反向条件:

select t1.*from table1 t1 inner join
       (select val from table1 group by val having count(id) = 1)
         t2
 on t1.val = t2.val
 inner join
     (select val2 from table1 group by val2 having count(id) >1) t3
     on t1.val2 = t3.val2
Run Code Online (Sandbox Code Playgroud)

在此处找到这两个查询的小提琴。


Suj*_*y30 7

请原谅任何错误,因为这将是我在本论坛的第一个答案。你也可以试试下面的,我同意窗口函数的答案。

SELECT t.*
FROM   table1 t 
WHERE  t.val IN (SELECT val 
                   FROM table1 
                 GROUP BY val 
                 HAVING COUNT(val) > 1 
                    AND COUNT(val) = COUNT(DISTINCT val2)
                 )
AND    t.val NOT IN (SELECT t.val
                     FROM   table1 t
                     WHERE  EXISTS (SELECT 1
                             FROM   table1 tai
                             WHERE  tai.id != t.id
                             AND    tai.val2 = t.val2));
Run Code Online (Sandbox Code Playgroud)

/* where 子句的第一部分确保我们在列 val2 中有不同的值,用于列 val 中的重复值

带有 not in 的 where 子句的第二部分告诉我们,对于列 val2 中的值,不同 id 之间没有值共享 */

--逆序查询(不确定给出预期结果)

SELECT t.*
FROM   table2 t
WHERE  t.val IN (SELECT val FROM table2 GROUP BY val HAVING COUNT(val) = 1)
AND    t.val2 IN (SELECT t.val2
                  FROM   table2 ta
                  WHERE  EXISTS (SELECT 1
                          FROM   table2 tai
                          WHERE  tai.id != ta.id
                          AND    tai.val = ta.val));
Run Code Online (Sandbox Code Playgroud)