簡體   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