2017-07-17 1 views
1

dans l'exemple de tableau ci-dessous - Tableau A, nous avons des entrées pour quatre ID différents 1,2,3,4 avec le statut respectif et son heure. Je voulais trouver le "ID" qui a pris le maximum de temps pour changer le "Statut" de Démarré à Terminé. Dans l'exemple ci-dessous, c'est ID = 4. Je voulais lancer une requête et trouver les résultats, où nous avons actuellement environ un million d'enregistrements dans une table. Ce serait vraiment génial, si quelqu'un fournit un moyen efficace de récupérer ces données.Recherche de la différence de date maximale sur une seule colonne

Tableau A

ID Status   Date(YYYY-DD-MM HH:MM:SS) 
1. Started  2017-01-01 01:00:00 
1. Completed  2017-01-01 02:00:00 
2. Started  2017-10-02 03:00:00 
2. Completed  2017-10-02 05:00:00 
3. Started  2017-15-03 06:00:00 
3. Completed  2017-15-03 09:00:00 
4. Started  2017-22-04 10:00:00 
4. Completed  2017-22-04 15:00:00 

Merci! Bruce

+3

MySQL <> SQL Server. Veuillez marquer celui que vous utilisez. –

+0

Qu'avez-vous essayé jusqu'à présent? S'il vous plaît fournir votre code. –

+0

En fait, j'exécutais différentes requêtes. select * de la table où status = 'completed' par Date desc. Et puis a pris quelques ID récents qui sont en état «terminé». sélectionnez Date de la table où ID dans (1,2,3,4) et vérifiait manuellement la différence maximale entre les dates pour chaque ID donné. Je me demandais si je pouvais écrire une sous-requête ou une auto-jointure pour récupérer les enregistrements, car j'ai actuellement 1 million d'enregistrements sur la table et il est difficile de vérifier chaque enregistrement manuellement. Votre aide serait très appréciée. Merci! – Bruce

Répondre

0

Je n'ai pas exécuté ce sql mais cela peut résoudre votre problème.

select a.id, max(DATEDIFF(SECOND, a.date, b.date + 1)) from TableA as a 
join TableA as b on a.id = b.id 
where a.status="started" and b.status="completed" 
+0

Merci pour vos contributions. – Bruce

0
SELECT 
    started.ID, timediff(completed.date, started.date) as elapsed_time 
FROM TABLE_A as started 
INNER JOIN TABLE_A as completed ON (completed.ID=started.ID AND completed.status='Completed') 
WHERE started.status='Started' 
ORDER BY elapsed_time desc 

être sûr qu'il ya un index sur TABLE_A pour l'ID de colonnes, la date

+1

Merci pour vos contributions. – Bruce

0

Vous pouvez interroger comme ci-dessous:

Select top 1 with ties Id from #yourDate y1 
    join #yourDate y2 
On y1.Id = y2.Id 
    and y1.[STatus] = 'Started' 
    and y2.[STatus] = 'Completed' 
    order by Row_number() over(order by datediff(mi,y1.[Date], y2.[date]) desc) 
+0

Merci pour vos contributions. – Bruce

0

Voici une manière avec une sous-requête corrélée. Il suffit de décommenter le TOP 1 pour obtenir l'ID 4 dans ce cas. Ceci est basé sur vos commentaires qu'il y a seulement 1 enregistrement "commencé", mais pourrait être plusieurs enregistrements "terminés" pour chaque ID.

declare @TableA table (ID int, Status varchar(64), Date datetime) 
insert into @TableA 
values 
(1,'Started','2017-01-01 01:00:00'), 
(1,'Completed','2017-01-01 02:00:00'), 
(2,'Started','2017-02-10 03:00:00'), 
(2,'Completed','2017-02-10 05:00:00'), 
(3,'Started','2017-03-15 06:00:00'), 
(3,'Completed','2017-03-15 09:00:00'), 
(4,'Started','2017-04-22 10:00:00'), 
(4,'Completed','2017-04-22 15:00:00') 


select --top 1 
    s.ID 
    ,datediff(minute,s.Date,e.EndDate) as TimeDifference 
from @TableA s 
inner join(
    select 
     ID 
     ,max(Date) as EndDate 
    from @TableA 
    where Status = 'Completed' 
    group by ID) e on e.ID = s.ID 
where 
    s.Status = 'Started' 
order by 
    datediff(minute,s.Date,e.EndDate) desc 

RETOURS

+----+----------------+ 
| ID | TimeDifference | 
+----+----------------+ 
| 4 |   300 | 
| 3 |   180 | 
| 2 |   120 | 
| 1 |    60 | 
+----+----------------+ 
+0

Merci beaucoup d'avoir fourni les détails. Cela a vraiment fonctionné! Appréciez votre temps et aidez. Merci :) – Bruce

+0

Ne pas oublier @Bruce, https://stackoverflow.com/help/someone-answers – scsimon

0

Si vous savez que « commencé » sera toujours le plus tôt dans le temps pour chaque ID et le dernier « terminé » enregistrer que vous envisagez sera toujours la dernière point dans le temps pour chaque ID, ce qui suit devrait avoir de bonnes performances pour un grand nombre d'enregistrements:

SELECT TOP 1 
     id 
    , DATEDIFF(s, MIN([Date]), MAX([date])) AS Elapsed 
FROM @TableA 
GROUP BY ID 
ORDER BY DATEDIFF(s, MIN([Date]), MAX([date])) DESC 
+0

Cela fonctionne beaucoup plus vite. Merci pour vos précieuses contributions! – Bruce