2009-02-09 4 views
0

Salut, je ne suis pas bon dans les questions de cadrage. Je ferai de mon mieux. Je crée un site Web et ma question est liée aux requêtes liées au site. C'est la requête actuelle que j'ai.Question d'interrogation liée à la récupération de l'entrée la plus récente d'une table?

SELECT 
    GPS_modem.vehicle_no, 
    vehicle_log.longitude, 
    vehicle_log.latitude, 
    vehicle_log.timestamp 
FROM 
    vehicle_log, 
    GPS_modem 
WHERE 
    GPS_modem.modem_ID = vehicle_log.modem_ID 
ORDER BY 
    timestamp desc 

Ce que je veux afficher est l'entrée avec l'horodatage le plus récent de la table vehicle_log où le modem_ID de la table GPS_modem correspond à la modem_ID de la table vehicle_log.

J'ai essayé d'utiliser DISTINCT mais je n'ai pas fonctionné. Je recevais des erreurs lorsque j'ai essayé d'utiliser la fonction MAX. J'espère que vous êtes en mesure de comprendre ma question, si alors s'il vous plaît aidez-moi. Vous remerciant à l'avance.

+0

Voulez-vous obtenir un seul enregistrement de la requête à savoir avec la plupart timestamp récente ? –

+0

Non, je veux obtenir plusieurs enregistrements. J'ai essayé en sélectionnant TOP qui a abouti à seulement 1 enregistrement. Pour chaque véhicule_no qui correspond au modem_ID de la première table, je veux afficher l'entrée récente. J'espère que vous avez compris. –

+0

Si je vous ai bien compris, vous voulez afficher les données les plus récentes (c'est-à-dire en utilisant l'horodatage) pour chaque modem/véhicule? –

Répondre

1

Selon DB,

SELECT TOP 1 GPS_modem.vehicle_no, vehicle_log.longitude, vehicle_log.latitude, vehicle_log.timestamp from vehicle_log,GPS_modem where GPS_modem.modem_ID = vehicle_log.modem_ID order by timestamp desc 

travaillera sur SQL Server.

+0

Oui, cela ne donnera qu'un seul résultat. Je veux afficher l'entrée récente pour chaque vehicle_no qui correspond au modem_id dans les deux tables. –

0

En MySQL, vous pouvez utiliser 'limite 1' à la fin de la requête.

0

Ce n'est peut-être pas la meilleure solution.

Mais puisque vous commandez les résultats, vous pouvez utiliser LIMIT.

SELECT GPS_modem.vehicle_no, vehicle_log.longitude, vehicle_log.latitude, vehicle_log.timestamp from vehicle_log,GPS_modem where GPS_modem.modem_ID = vehicle_log.modem_ID order by timestamp desc LIMIT 1

Il existe d'autres solutions (probablement de meilleurs), mais cela est une option.

4

Vous pouvez utiliser la sous-requête corrélative:

SELECT 
    m.vehicle_no, 
    l.longitude, 
    l.latitude, 
    l.timestamp 
FROM 
    vehicle_log AS l, 
    GPS_modem AS m 
WHERE 
    m.modem_ID = l.modem_ID 
    AND l.timestamp = (
    SELECT MAX(timestamp) FROM vehicle_log WHERE modem_ID = l.modem_ID 
) 

EDIT: Dans la révision n ° 1 de ma réponse, j'avais la requête vu ci-dessus. Puis quelque chose m'a fait penser que je devais le remplacer par celui ci-dessous. Celui ci-dessous fonctionne mais est inutile compliqué, très probablement plus mauvais. Ayant dormi dessus, je recommande contre cette approche. ;-)

SELECT 
    m.vehicle_no, 
    latest.longitude, 
    latest.latitude, 
    latest.timestamp 
FROM 
    GPS_modem AS m, 
    (
    SELECT 
     modem_ID, 
     longitude, 
     latitude, 
     timestamp 
    FROM 
     vehicle_log AS l 
    WHERE 
     timestamp = (
     SELECT MAX(timestamp) FROM vehicle_log WHERE modem_ID = l.modem_ID 
    ) 
) AS latest 
WHERE 
    m.modem_ID = latest.modem_ID 
+0

Si je peux attirer votre attention sur la solution que j'ai posté ci-dessous. Le même résultat est obtenu en utilisant une seule sous-requête et aucune exigence pour une table dynamique. –

+0

Je ne suis pas sûr des différences de performances, mais vous pouvez le faire en utilisant la même logique mais sans la sous-requête ... – MatBailie

+0

SELECT * FROM vehicle_log AS l, GPS_modem AS m OERE timestamp = (SELECT MAX (horodatage) FROM véhicule_log OERE modem_ID = l.modem_ID) ET m.modem_ID = latest.modem_ID – MatBailie

0

Voici un exemple d'utilisation de SQL Server. Il utilise une sous-requête corrélée avec l'avantage d'effectuer une correspondance en utilisant modem_ID plutôt qu'une correspondance d'égalité d'horodatage.

CREATE TABLE #GPS_modem 
(
    ID INT IDENTITY(1,1) PRIMARY KEY, 
    vehicle_no VARCHAR(10) 
) 

CREATE TABLE #vehicle_log 
(
    ID INT IDENTITY(1,1) PRIMARY KEY, 
    modem_ID INT, 
    longitude INT, 
    latitude INT, 
    [timestamp] DATETIME DEFAULT GETDATE() 
) 

INSERT INTO #GPS_modem 
SELECT 'ABC123' UNION ALL SELECT 'XYZ123' 

INSERT INTO #vehicle_log 
SELECT 1,234,543,GETDATE() 
UNION all 
SELECT 2,4342,432234,GETDATE() 
UNION all 
SELECT 1,4322,432,DATEADD(DAY,-1,GETDATE()) 
UNION all 
SELECT 2,6336,5324,DATEADD(DAY,-1,GETDATE()) 

SELECT * FROM #GPS_modem 
SELECT * FROM #vehicle_log 


SELECT 
    vehicle_no, 
    longitude, 
    latitude, 
    [timestamp] 
FROM 
    #GPS_modem A 
     inner join #vehicle_log B on 
     A.ID = B.modem_ID 
WHERE B.ID IN 
(
    SELECT TOP 1 ID 
    FROM #vehicle_log 
    WHERE modem_ID = A.ID 
    ORDER BY [timestamp] DESC 
) 

DROP TABLE #GPS_modem 
DROP TABLE #vehicle_log 

Cheers, John

+0

Vous indiquez l'existence d'un champ ID qui peut ou ne peut pas être là. – Tomalak

0

Dans Oracle:

SELECT 
    GPS_modem.vehicle_no, 
    vehicle_log.longitude, 
    vehicle_log.latitude, 
    vehicle_log.timestamp 
FROM 
    (
    SELECT v.*, ROW_NUMBER() OVER (PARTITION BY modem_id ORDER BY timespace DESC) AS rn 
) l, GPS_modem m 
WHERE 
    l.rn = 1 
    AND m.modem_ID = l.modem_ID 

MySQL:

SELECT * 
FROM (
    SELECT DISTINCT g.id AS gid, (
    SELECT l.modem_id 
    FROM vehicle_log l 
    WHERE l.modem_id = g.modem_id 
    ORDER BY timestemp DESC 
    LIMIT 1 
    ) lid 
), vehicle_log lo, GPS_modem go 
WHERE lo.modem_id = lid 
    AND go.modem_id = lo.modem_id 
Questions connexes