2013-03-28 2 views
0

j'ai un ensemble de données comme celui-ciGroupe par date et et vérifier les dates continues

date1  Price Availability ServiceID 
2012-10-01 50  1    5 
2012-10-02 60  1    5 
2012-10-03 60  1    5 
2012-10-04 60  1    5 
2012-10-06 60  1    5 
2012-10-07 60  0    5 
2012-10-08 60  1    5 

Maintenant, je veux vérifier quel est le prix total, min disponibilité et Serviceid pour une période donnée

Par exemple

from 2012-10-01 to 2012-10-03 results would be 170, availability 1 and serviceID 5 
from 2012-10-06 to 2012-10-08 results would be 180, availability 0! and serviceID 5 
from 2012-10-04 to 2012-10-06 results would be 120, availability 1! and serviceID 5 BUT there is a date missing so availability is 0! 

J'ai essayé quelque chose comme

select date1, sum(price), min(availability), service from #t 
group by date1, price, availability, service 
having count(date1) = datediff(day, @startdate, @enddate) 

Cela ne fonctionne pas parce que si je groupe par date1, alors compte pas valide. Ne sait pas comment obtenir la somme, la disponibilité min et vérifier les dates en continu.

EDIT Si un jeu de résultats doit contenir des spécifications détaillées. et filtrer les résultats avec min (disponibilité) = 0 ou la date non continue

For example 
from 2012-10-01 to 2012-10-03 results would be 170, availability 1 and serviceID 5 

date1  Price Availability ServiceID 
    2012-10-01 50  1    5 
    2012-10-02 60  1    5 
    2012-10-03 60  1    5 

from 2012-10-06 to 2012-10-08 results would be 180, availability 0! and serviceID 5 
date1  Price Availability ServiceID 

from 2012-10-04 to 2012-10-06 results would be 120, availability 1! and serviceID 5 BUT 
date1  Price Availability ServiceID 
+0

Comment pourrait-il être de 2012-10-04 à 2012-10-06 être de 180 s'il y a 2 valeurs avec 60 chacune? Avez-vous besoin d'un «faux» 60 pour la date manquante? –

+0

@NenadZivkovic typo – mko

Répondre

2

Essayez ceci:

select sum(price) As TotalPrice, 
     service, 
     Case When Count(*) = DateDiff(Day, @Startdate, @EndDate) + 1 
       Then Min(Availability) 
       Else 0 End As Availability 
from #T 
Where Date1 >= @StartDate 
     And Date1 <= @endDate 
group by service 

En filtrant la date dans une clause where en fonction des dates, et non le regroupement à la date, cela vous permet d'obtenir un nombre ou des lignes que vous pouvez ensuite faire correspondre à la date diff. Notez que vous devez ajouter 1 à la date diff car DateDiff d'hier à aujourd'hui est seulement 1 mais représenterait 2 lignes dans vos données source.

Je devrais également mentionner que cela ne vérifie pas vraiment les dates continues. Il recherche simplement un nombre de lignes correspondant au nombre de jours calculé. En fonction de votre commentaire et de votre modification, vous pouvez essayer cette solution de table dérivée.

Select T.date1, 
     SummaryData.TotalPrice, 
     SummaryData.Availability, 
     T.Service 
From #T T 
     Inner Join (
      select sum(price) As TotalPrice, 
      service, 
       Case When Count(*) = DateDiff(Day, @Startdate, @EndDate) + 1 
        Then Min(Availability) 
        Else 0 End As Availability 
      from #T 
      Where Date1 >= @StartDate 
        And Date1 <= @endDate 
      group by service 
      Having Case When Count(*) = DateDiff(Day, @Startdate, @EndDate) + 1 
         Then Min(Availability) 
         Else 0 End = 1 
      ) As SummaryData 
      On T.Service = SummaryData.Service 
Where Date1 >= @StartDate 
     And Date1 <= @endDate 
+0

fondamentalement j'aurais besoin d'un cte ou d'une table de temp. il ne peut pas être résolu dans une requête? – mko

+0

@G Mastros pourriez-vous s'il vous plaît vérifier modifier une partie de ma question? – mko

+0

Il est possible de créer la même sortie que ci-dessus sans utiliser de CTE, mais il peut être impossible d'inclure les détails sans utiliser un CTE sauf si vous utilisez une version plus récente de SQL Server. Quelle version utilisez-vous? –

0

S'il n'y avait pas de mise en abyme avec des dates manquantes, la requête serait assez simple:

SELECT SUM(price), MIN(availability) AS Availibility, MIN(serviceID) AS serviceID FROM #t 
WHERE date1 BETWEEN @Startdate AND @enddate 

Howere, trouver des dates manquantes nécessite un CTE supplémentaire, je vais utiliser idée de t-sql get all dates between 2 dates et peut ressembler à ceci:

;WITH dates AS (
    SELECT @startdate AS dt 
    UNION ALL 
    SELECT DATEADD(dd, 1, dt) 
    FROM dates s 
    WHERE DATEADD(dd, 1, dt) <= @enddate 
) 
SELECT SUM(price), 
CASE 
    WHEN EXISTS (SELECT * FROM dates WHERE dt NOT IN (SELECT date1 FROM #t WHERE date1 BETWEEN @Startdate AND @enddate)) THEN 0 
    ELSE MIN(availability) 
END AS Availibility, 
MIN(serviceID) AS serviceID FROM #t 
WHERE date1 BETWEEN @Startdate AND @enddate 
+1

Pendant que je tapais G Mastros, j'ai aussi posté une solution que j'aime mieux que la mienne :) mais j'ai aussi décidé de poster celle-ci. Ne fait pas de mal à regarder de deux côtés. –

Questions connexes