2009-09-03 9 views
4

J'ai une application web qui permet à un client de définir un tarif journalier pour son service. Pour un jour donné, le client peut entrer deux taux, un taux horaire (rateTypeId = 1) et un dailyRate (rateTypeId = 2). Ces taux sont souvent attribués à l'avance, et ils changent souvent. J'ai besoin de suivre toutes les affectations, mais seulement tirer le dernier taux assigné.Mysql join basé sur max (timestamp)

J'ai deux tables. La première table définit simplement ma structure tarifaire et ressemble à ceci (simplifié):

Tableau: RateDefinitions

RATECODE ----- RATE 
31 ---------------- 5.00 
32 ---------------- 6.00 
33 ---------------- 7.00 

Ma deuxième table suit les taux attribués aux dates indiquées. Plus d'un taux peut être attribué à une date donnée, mais nous n'utiliserons que le dernier taux basé sur le 'entrytimestamp'.

Tableau: Taux

ID --- RATETYPEID --- RATECODE ------ DATE -------- ENTRYTIMESTAMP 
1 ---------- 1 --------------- 31 ---------- 20091010 ---------- 1100000000 
2 ---------- 2 --------------- 33 ---------- 20091010 ---------- 1100000000 
3 ---------- 1 --------------- 32 ---------- 20091010 ---------- 1200000000 

Maintenant, je vais avoir du mal à mettre ensemble une requête qui va tirer toutes les dernières missions de taux pour une période donnée.

J'ai essayé:

select r.id, r.rateTypeId, r.rateCode, max(r.entryTimestamp), rd.rate 
from rates r 
join rateDefinitions rd 
on r.rateCode=rd.rateCode 
where date=20091010 
group by startDate, rateTypeId 

Mais cela ne va pas le faire. Je pense que j'ai besoin d'une jointure sur une instruction de sous-sélection, mais je ne suis pas sûr. Mes résultats doivent contenir deux lignes par date, similaires à:

ID --- RATETYPEID --- RATECODE ---------- ENTRYTIMESTAMP ----- RATE 
3 ----------- 1 --------------- 32 -------------------- 1200000000 ----------6.00 
2 ----------- 2 --------------- 33 -------------------- 1100000000 ----------7.00 

Merci pour vos suggestions.

Répondre

2

Ce problème est assez commun. Vous avez besoin d'une sous-requête pour exclure l'horodatage max et le ratetypeid (qui est la base du regroupement), puis sélectionner tout le reste à partir d'une jointure interne de ces sous-requêtes et de tout le reste.

Pour MySQL:

SELECT ratecode, rate, id, ratetypeid, date, entrytimestamp 

FROM ratedefinitions, 
(SELECT ratetypeid, MAX(entrytimestamp) AS max_timestamp FROM Rates 
GROUP BY ratetypeid) AS inner_table 

WHERE 

inner_table.ratetypeid = ratetypeid 
AND innertable.max_timestamp = timestamp 
+0

Merci à Crimson et Doug Hayes. Les théories ici ont aidé à résoudre le problème. – user167850

0

Je recommande une sous-requête:

select r.id, r.rateTypeId, r.rateCode, max(r.entryTimestamp), rd.rate 
from 
rateDefinitions rd, 
rate r, 
    (select 
     rateCode, max(entryTimestamp) maxEntryTimestamp 
    from 
     rate 
    where date=20091010 
    group by rateCode) latestRates 

where r.rateCode=rd.rateCode AND 
    r.rateCode = latestRates.rateCode AND 
    r.entryTimestamp = latestRates.maxEntryTimestamp 
group by startDate, rateTypeId 

Il y a une grosse supposition de ma part ici. C'est-à-dire que dans la table de taux, pour une date donnée et un code de rat, les horodatages d'entrée sont uniques.