簡體   English   中英

SQL從“歷史記錄”中返回首次記錄的日期

[英]SQL to return first recorded date from All-time Records

釣魚數據庫存儲歷史記錄。 但是,當某人具有共同記錄時,我想恢復為真實記錄的第一個捕獲。

select * 
from T 
inner join (select Type, 
                   Name, 
                   max(TotDrams) as maxdrams 
            from T 
            WHERE Type='Common Bream' 
            group by Type, Name 
           ) sq on T.Type = sq.Type 
                and T.Name = sq.Name 
                and sq.maxdrams = T.TotDrams 
ORDER BY Ranking ASC

上面的返回所有名稱的每個記錄的最佳捕獲的所有時間記錄,但是當一個記錄聯合時,它自然會返回附加記錄。 我只希望最早的日期記錄包含在所有時間記錄中。

有沒有一種方法可以改編上面的代碼以刪除附加的聯合記錄並僅選擇最早的記錄?

Fishname     Rank            Weight           Angler            Date

Slimey       Rank 1        2 lb   3 oz      John Budd         30/11/2013
Fishy        Rank 2        1 lb   15 oz     Chris Clot        12/01/2009
Scales       Rank 3        1 lb   12 oz     John Budd         21/03/2014
Scales       Rank 3        1 lb   12 oz     Harry White       01/04/2002

對於上面的示例-當前正在發生的情況,我想刪除John Budd的聯合記錄,因為它是聯合的而不是原始的。

另一個注意事項:-該SQL將與php一起使用。

您可以在捕獲每種魚的最早日期中添加另一個聯接。 就像是:

select * 
from T 
inner join (select Species, 
                   FishName, 
                   max(TotalDrams) as maxdrams 
            from T 
            WHERE Species='Common Bream' 
            AND DateCaught <> ''
            group by Species, FishName 
           ) sq on T.Species = sq.Species 
                and T.FishName = sq.FishName 
                and sq.maxdrams = T.TotalDrams 
inner join (select Species, 
                   FishName, 
                   min(DateCaught) as minDate 
            from T 
            WHERE Species='Common Bream' 
            AND DateCaught <> ''
            group by Species, FishName 
           ) sq2 on T.Species = sq2.Species 
                and T.FishName = sq2.FishName 
                and sq2.minDate = T.DateCaught 
where T.DateCaught <> ''
ORDER BY Rank ASC

然后,您可以將這兩個條件重構為單個聯接:

select * 
from T 
inner join (select Species, 
                   FishName, 
                   max(TotalDrams) as maxdrams,
                   min(DateCaught) as minDate 
            from T 
            WHERE Species='Common Bream' 
            AND DateCaught <> ''
            group by Species, FishName 
           ) sq on T.Species = sq.Species 
                and T.FishName = sq.FishName 
                and sq.maxdrams = T.TotalDrams 
                and sq.minDate = T.DateCaught 
where T.DateCaught <> ''
ORDER BY Rank ASC

編輯:

對數據結構的進一步分析表明,上面的答案不太正確-由於日期是varchar,並且它對數據結構的假設不正確,因此它正在過濾掉幾條記錄。下面是對答案的修改:

select distinct 
   T.species,
   t.fishname,
   t.rank,
   t.pounds,
   t.ounces,
   t.drams,
   t.totaldrams,
   t.peg,
   t.angler,
   sq.*,
   sq2.*
FROM (select Species, 
             FishName, 
              max(TotalDrams) as maxdrams
      from T 
      WHERE Species='Common Bream' 
      group by Species, FishName 
     ) sq 
inner join (select Species, 
                   FishName, 
                   TotalDrams,
                   min(if(DateCaught='',STR_TO_DATE('31/12/3099','%d/%m/%Y'),STR_TO_DATE(DateCaught,'%d/%m/%Y'))) as minDate 
            from T 
            WHERE Species='Common Bream' 
            group by Species, FishName, TotalDrams 
           ) sq2 on sq.Species = sq2.Species 
                 and sq.FishName = sq2.FishName 
                 and sq.MaxDrams = sq2.TotalDrams
inner join T on sq.species = T.species 
and sq.fishname = T.fishname
and sq.maxdrams = T.totaldrams
and sq2.mindate = if(DateCaught='',STR_TO_DATE('31/12/3099','%d/%m/%Y'),STR_TO_DATE(DateCaught,'%d/%m/%Y'))

排名后按日期排序,然后按魚名分組。 看起來可行嗎?

select * from T inner join (select Species, FishName, max(TotalDrams) as maxdrams from T WHERE Species='Common Bream' group by Species, FishName ) sq on T.Species = sq.Species and T.FishName = sq.FishName and sq.maxdrams = T.TotalDrams GROUP BY T.FishName ORDER BY Rank, DateCaught ASC

我處理此問題的方式略有不同,而不是嘗試將結果限制為最大,我將排除不是的結果。 因此,使用類似:

SELECT  T.*
FROM    T
        LEFT JOIN T AS T2
            ON T2.Species = T.Species
            AND T2.FishName = T.FishName
            AND (T2.TotalDrams < T.TotalDrams
                OR (T.TotalDrams = T2.TotalDrams AND T2.DateCaught > T.DateCaught))
WHERE   T.Species = 'Common Bream'
AND     T2.Species IS NULL
ORDER BY T.Rank ASC;

這使用標准的LEFT JOIN/IS NULL方法來排除相同魚類型的記錄,並且其中之一:

  • TotalDramsTotalDrams

要么

  • 具有相同的TotalDrams更高的DateCaught

SQL小提琴示例

由於MySQL實現子查詢的方式,您可能還會發現它比未提供所需結果的原始查詢執行得更好!


編輯

好的,新方法。 我認為解決此問題的最佳方法是使用變量為每條記錄存儲一個新的行號,然后可以對前1個進行過濾。以下內容將根據排序條件分配行號:

SELECT  @r:= CASE WHEN @f = t.FishName AND @s:= t.Species 
                    THEN @r + 1 
                ELSE 1 
            END AS RowNum,
        @f:= t.FishName AS FishName,
        @s:= t.Species AS Species,
        t.Rank,
        t.Pounds,
        t.Ounces,
        t.Drams,
        t.TotalDrams,
        t.Peg,
        t.Angler,
        STR_TO_DATE(IF(t.DateCaught = '', '31/12/2050', t.DateCaught), '%d/%m/%Y')  AS DateCaught
FROM    T
        CROSS JOIN (SELECT  @f:= '',@s:='', @r:= 0) AS v
ORDER BY t.FishName, t.Species, t.TotalDrams DESC, DateCaught ASC;

然后,您可以將其放入子查詢中,並將記錄限制在前1個:

SELECT  *
FROM    (   SELECT  @r:= CASE WHEN @f = t.FishName AND @s = t.Species 
                                THEN @r + 1 
                            ELSE 1 
                        END AS RowNum,
                    @f:= t.FishName AS FishName,
                    @s:= t.Species AS Species,
                    t.Rank,
                    t.Pounds,
                    t.Ounces,
                    t.Drams,
                    t.TotalDrams,
                    t.Peg,
                    t.Angler,
                    t.DateCaught
            FROM    T
                    CROSS JOIN (SELECT  @f:= '',@s:='', @r:= 0) AS v
            ORDER BY t.FishName, t.Species, t.TotalDrams DESC, STR_TO_DATE(IF(t.DateCaught = '', '31/12/2050', t.DateCaught), '%d/%m/%Y') ASC
        ) AS t
WHERE   t.RowNum = 1
ORDER BY t.Rank ASC;

SQL小提琴示例

如果要添加更多規則(即,如果兩個權重相同且在同一日期),則這是最靈活的方法,可以向子查詢(例如Angler添加進一步的排序。 這樣就保證了每個元組(魚的名稱,種類)只有一個記錄,並且給定足夠的順序就可以確定結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM