【问题标题】:How do I use SQL/mySQL to select rows where 2 columns have multiple of the same value and 1 column has a distinct value?如何使用 SQL/mySQL 选择 2 列具有多个相同值且 1 列具有不同值的行?
【发布时间】:2017-10-22 22:09:26
【问题描述】:

exTab

 PK     col1     col2     col3
 ---------------------------------
 1      val1     val4     val7   **want to return this row only
 2      val1     val4     val8
 3      val1     val4     val8
 4      val1     val5     val9
 5      val2     val5     val9
 6      val2     val5     val9
 7      val2     val6     val0
 8      val3     val6     val0

如何使用 SQL(使用 mySQL)仅返回 col1 中具有多个相同值且 col2 中具有多个相同值但在 col 3 中具有唯一值的行?

例如,在上表(exTab)中,val1 在 col1 中出现 4 次,对于这 4 次出现,val4 在 col2 中出现 3 次,但是对于这 3 次出现,val7 在 col3 中仅出现一次,所以我想返回这一行(第 1 行)。给定条件,第 1 行将是我希望从此表返回的唯一行。

我尝试了各种与 group by 的组合,count > 1,distinct,where not exits,等等都无济于事。这是我的第一篇文章,如果我做错了什么,我深表歉意。

【问题讨论】:

  • 您应该包含您尝试过的内容,否则您的问题可能被解释为要求我们代替您完成您的工作。这样的问题很可能会吸引反对票和接近票。
  • 感谢@Shadow 的建议。看起来我最接近的是基于 FuzzyTree 的解决方案 stackoverflow.com/questions/23860490/…>。但我搞砸了添加第二个连接的语法,他的解决方案不需要,但你搞定了。

标签: mysql sql


【解决方案1】:

我会通过结合两个子查询的结果来做到这一点:

在子查询 1 中,我会得到多次出现的 col1-col2 组合。

在子查询 2 中,我会得到只出现一次的 col1-col2-col3 组合。

这 2 个子查询的交集(内连接)将产生您正在寻找的记录。

select t1.*
from
    exTab t1
    inner join
        (select col1, col2 from exTab
         group by col1, col2
         having count(*)>1) t2
    inner join
        (select col1, col2, col3 from exTab
         group by col1, col2, col3
         having count(*)=1) t3 on t2.col1=t3.col1
                              and t2.col2=t3.col2
                              and t1.col1=t3.col1
                              and t1.col2=t3.col2
                              and t1.col3=t3.col3

【讨论】:

  • 再次感谢@Shadow。当针对实际的 140K 行运行时,看起来这个任务完美地完成了这项工作。
【解决方案2】:

如果我很好地理解了这个 SQL 查询可能会帮助你的问题:

SELECT 
    SubTab.PK 
FROM 
    (SELECT  
         PK, 
         COUNT(col3) OVER (PARTITION BY col1) as col1_group,
         COUNT(col3) OVER (PARTITION BY col2) as col2_group
     FROM 
         exTab) SubTab
WHERE 
    SubTab.col1_group = 1 AND SubTab.col2_group = 1;

它将在原始选项卡上运行两个窗口聚合函数,然后返回临时选项卡,并且从该选项卡中,我们只选择 col3 在一组中唯一的行的 PK,而另一组也是唯一的。

【讨论】:

  • 只有 mysql v8.0 支持窗口函数,目前还处于 alpha 状态...
  • 我无法尝试这个,因为我使用的是 mySQL 5.6.14。但是感谢您的知识,@Take_Care_。
【解决方案3】:

您可以尝试以下方式:

SELECT
    *
    FROM table 
    WHERE col1 IN (SELECT col1 FROM table GROUP BY 1 HAVING count(*)>1)
    AND col2 IN (SELECT col2 FROM table GROUP BY 1 HAVING count(*)>1)
    AND col3 IN (SELECT col3 FROM table GROUP BY 1 HAVING count(*)=1)

虽然如果你的表很大,性能可能会很糟糕。

【讨论】:

  • 这个没有使用实际数据返回所需的行,但感谢您参与并提供解决方案,@jcaron。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-25
  • 2014-12-08
  • 1970-01-01
  • 2017-12-24
  • 2014-07-14
  • 2021-12-03
  • 1970-01-01
相关资源
最近更新 更多