繁体   English   中英

我如何选择其中某些字段重复但其他字段在MySQL中进行比较的行

[英]How do i select rows where some fields are duplicated but other fields are compared in mySql

我有一张桌子。 4个领域。 如何在“ Species找到具有重复值且在“ Location中具有重复值的记录,并在其他记录中将FooBar进行比较? (我在寻找Foo而不是Bar

RecordId    Species   Location    Foo    Bar
1           Cat       home        4      9
2           Dog       home        4      9
3           Cat       home        3      7
4           Bunny     home        4      9
5           Cat       home        1      2

我想找到记录1和3。它们都具有Cat(在Species )和home(在Location ),并且Foo在记录1中的值为4 ,小于在记录3中的Bar (即7 )。 记录5不匹配,因为记录1中的Foo不小于记录5中的Bar

如果我没有正确说出问题,请不要仅仅关闭它。 如果需要,我很乐意进行编辑。

让我们分解一下:

第1部分:在Field1Field2中共享重复值的记录:

这很简单。 下面的查询返回所有(Species + Location)元组,它们在源表中多次出现。

SELECT
    Species,
    Location
FROM
    table
GROUP BY
    Species,
    Location
HAVING
    COUNT(*) > 1

这给出了以下结果:

Species   Location
Cat       home

然后,我们要获取具有这些已知重复值的原始原始记录(非分组记录),可以通过在原始表上进行一次INNER JOIN来做到这一点:

SELECT
    table.*
FROM
    table
    INNER JOIN
    (
        SELECT
            Species,
            Location
        FROM
            table
        GROUP BY
            Species,
            Location
        HAVING
            COUNT(*) > 1
    ) AS duplicates ON
        table.Species  = duplicates.Species AND
        table.Location = duplicates.Location

(将它作为WHERE子查询可能很诱人,但是灵活性较差,并且对问题的思考方式较少“关系”式)

然后得出以下结果:

RecordId    Species   Location  Foo    Bar
1           Cat       home      4      9
3           Cat       home      3      7
5           Cat       home      1      2

第2部分:基于FooBar过滤器:

这更加复杂...这是您给的规则:

  • 记录1:之所以包含,是因为记录的Foo == 4小于记录3的Bar == 7
  • 记录3:您不解释为什么除了满足重复条件的记录之外还包括记录3-或为什么当记录1的Bar = 9更高时,为什么使用记录3的Bar = 7与记录1进行比较。
  • 记录5:之所以排除,是因为记录1的Foo == 4大于记录5的Bar == 2

我的解释是,每个组内部(在这种情况下为记录1、3和5)仅返回Bar > MAX( Foo ) 在这种情况下, MAX( Foo ) == 4 ,所以分别包含记录1和3是因为9 > 47 > 4 ,但不是5并不是因为2 > 4为假。

我们将从先前的查询中获取组,并添加一个MAX聚合:

SELECT
    Species,
    Location,
    MAX( Foo ) AS MaxFoo
FROM
    table
GROUP BY
    Species,
    Location
HAVING
    COUNT(*) > 1

这给出了以下结果:

Species   Location    MaxFoo
Cat       home        4

(因为此查询是原始子查询的超集,所以我们不需要在第二个查询上进行JOIN ,但可以就地对其进行编辑):

SELECT
    table.*
FROM
    table
    INNER JOIN
    (
        SELECT
            Species,
            Location,
            MAX( Foo ) AS MaxFoo
        FROM
            table
        GROUP BY
            Species,
            Location
        HAVING
            COUNT(*) > 1
    ) AS duplicates ON
        table.Species  = duplicates.Species AND
        table.Location = duplicates.Location
WHERE
    table.Bar > duplicates.MaxFoo

并且此查询为您提供所需的结果:

RecordId    Species   Location  Foo    Bar
1           Cat       home      4      9
3           Cat       home      3      7

此查询还显示了MaxFoo查询(而不是WHERE子查询)执行JOIN操作的优势,因为您可以对数据执行更多操作(例如,如果要在输出中包括MaxFoo ,则只需将SELECT table.* FROM...更改为SELECT table.*, duplicates.MaxFoo FROM... )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM