2009-07-15 13 views
0

Cela va sembler une question boiteuse pour tous les experts dans les vues du serveur SQL, mais ...requête SQL: décalage horaire

J'ai donc un petit ensemble de données qui a besoin de mon client à des fins de reporting. Je dois admettre que bien que je leur ai demandé leurs exigences en matière de rapports, ce n'est pas jusqu'à maintenant que je vois que mon db pourrait être mieux optimisé.

L'un des morceaux de données qu'ils veulent est la différence de temps entre deux tâches qui ont pu fonctionner:

select caseid, hy.createdate 
from app_history hy 
where hy.activityid in (303734, 303724) 

Cela me donne deux lignes (après modification) par cas la soumission qui sont alors à mesurer ; mais quelques wiggles: L'activité 303734 sera toujours exécutée, l'activité 303724 pourrait s'exécuter. Chaque combinaison 303734 et 303724 correspond. En théorie, un cas peut avoir 1 303734 non apparié avec une paire appariée après la deuxième soumission. Faire correspondre ceux-ci pourrait être à l'intuition. Pas bon. Il peut y avoir plus d'une soumission par cas et, si c'est le cas, les deux activités seront exécutées à chaque fois. Il est impossible d'écrire le numéro de soumission dans cette table.

La table app_history contient les ID utilisateur, caseid et activityid en tant que clés étrangères. Le PK est l'identifiant de la colonne d'identité.

Existe-t-il un meilleur moyen d'écrire la requête?

AFter aide de KM:

select 
    c.id, c.submissionno, hya.caseid, hya.createtime, hyb.caseid, hyb.createtime 
    ,CASE 
     WHEN hyb.caseid IS NOT NULL THEN DATEDIFF(mi,hya.createtime,hyb.createtime) 
     ELSE NULL 
    END AS Difference 
    from app_case c 
     inner join app_history hya on c.id = hya.caseid 
     left outer join app_history hyb on c.id = hyb.caseid 
    where hya.activityid in (303734) and hyb.activityid in (303724) order by c.id asc 

Ce presque fonctionne.

J'ai maintenant cette question:

460509|2|460509|15:15:39.000|460509|15:16:13.000|1 
460509|2|460509|15:15:39.000|460509|15:18:13.000|3 
460509|2|460509|15:17:52.000|460509|15:16:13.000|-1 
460509|2|460509|15:17:52.000|460509|15:18:13.000|1 

Je reçois maintenant 1 rang comparant chacun des deux pour chacune des quatre lignes ... mmm Je pense qu'il est le meilleur que je peux espérer. :(

+0

Quand vous dites « toujours run "et" pourrait fonctionner ", est-ce que cela signifie que leur' createdate' n'a peut-être pas été défini/est 'NULL'? –

+0

Si l'activité n'est pas exécutée, elle ne sera pas écrite dans la table app.history. – Sean

+0

quelle version de SQL Server, et quel est le PK de app_history (est-ce une identité?) –

Répondre

1

UTILISATION LEFT JOIN

SELECT 
    a.caseid, a.createdate 
     ,b.caseid, b.createdate 
     ,CASE 
      WHEN b.caseid IS NOT NULL THEN DATEDIFF(mi,a.createdate,b.createdate) 
      ELSE NULL 
     END AS Difference 
    FROM app_history    a 
     LEFT OUTER JOIN app_history b ON b.activityid=303724 
    WHERE a.activityid=303734 

EDIT après un peu plus d'informations de schéma ...

SELECT 
    a.caseid, a.createdate 
     ,b.caseid, b.createdate 
     ,CASE 
      WHEN b.caseid IS NOT NULL THEN DATEDIFF(mi,a.createdate,b.createdate) 
      ELSE NULL 
     END AS Difference 
    FROM (SELECT MAX(ID) AS MaxID FROM app_history WHERE activityid=303734)     aa 
     INNER JOIN app_history                a ON aa.MaxID=a.ID 
     LEFT OUTER JOIN a(SELECT MAX(ID) AS MaxID FROM app_history WHERE activityid=303724) bb ON 1=1 
     LEFT OUTER JOIN app_history               b ON bb.MaxID=b.ID 
+0

Cela semble bien, merci KM. – Sean

+0

En fait, je pense que cela ne fonctionne pas ... Pas comme je l'attendais de toute façon. Il semble comparer chaque rangée «b» à chaque rangée «a». – Sean

+0

Salut, j'ai seulement 3649 lignes dans app.history en dev. Je reçois 55605 lignes retournées avec la requête ci-dessus. – Sean

0

faire quelque chose comme ça


select datediff(
day, 
(select isnull(hy.createdate,0) from app_history hy where hy.activityid =303734), 
(select isnull(hy.createdate,0) from app_history hy where hy.activityid =303724) 
)