[英]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
方法來排除相同魚類型的記錄,並且其中之一:
TotalDrams
值TotalDrams
要么
TotalDrams
值和更高的DateCaught
由於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;
如果要添加更多規則(即,如果兩個權重相同且在同一日期),則這是最靈活的方法,可以向子查詢(例如Angler
添加進一步的排序。 這樣就保證了每個元組(魚的名稱,種類)只有一個記錄,並且給定足夠的順序就可以確定結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.