2009-08-12 7 views
1

J'ai une table avec des lignes qui symbolisent les dates de commande:SQL sélectionner et compter tous les éléments qui se sont produits avant

2009-05-15 13:31:47.713 
2009-05-15 22:09:32.227 
2009-05-16 02:38:36.027 
2009-05-16 12:06:49.743 
2009-05-16 16:20:26.680 
2009-05-17 01:36:19.480 
2009-05-18 09:44:46.993 
2009-05-18 14:06:12.073 
2009-05-18 15:25:47.540 
2009-05-19 10:28:24.150 

Je voudrais avoir requête qui renvoie les éléments suivants:

2009-05-15 2 
2009-05-16 5 
2009-05-17 6 
2009-05-18 9 
2009-05-19 10 

Fondamentalement, il garde un total cumulé de toutes les commandes passées à la fin du jour de la date indiquée. Les commandes ne sont pas les commandes ce jour-là mais toutes les commandes depuis les premières dates dans le tableau.

Ceci est MSSQL 2000 et le type de données dans la première table est juste datetime, dans la seconde il pourrait être datetime ou chaîne, il n'a pas vraiment d'importance pour mes fins.

+0

système de base de données? –

+0

et quel type de données? – Brabster

+0

Voir mes modifications ci-dessus (en bas du message) – Matt

Répondre

7

Je suis arrivé que cela fonctionne sur SQL Server 2005. Je pense que il devrait fonctionner avec 2000, bien.

SELECT dt, count(q2.YourDate) 
    FROM (SELECT DISTINCT CONVERT(varchar,YourDate,101) dt FROM YourTable) t1 
    JOIN YourTable q2 ON DATEADD(d,-1,CONVERT(varchar,YourDate,101)) < dt 
    GROUP BY dt 

Ceci interrogera la table deux fois, mais donnera au moins une sortie correcte.

+0

C'est fait! Merci! – Matt

+0

+1, même solution de jointure de base que la mienne, mais sans la table dérivée supplémentaire. belle solution compacte! –

+0

+1 ici aussi, même solution de jointure de base que la mienne aussi, mais beaucoup plus compact et spécifique à Tsql pour démarrer. – PowerUser

0

Essayez cette (renvoie les dates de chaîne):

SELECT 
    LEFT(CONVERT(char(23),YourDate,121),10) AS Date 
     ,COUNT(*) AS CountOf 
    FROM YourTable 
    GROUP BY LEFT(CONVERT(char(23),YourDate,121),10) 
    ORDER BY 1 

cette numérisons de table. si elle est trop lente, pensez à utiliser une colonne calculée persistante avec un index pour la date, qui fonctionnera beaucoup plus vite. Cependant, I'mnot que si vous pouvez faire tout cela dans SQL 2000.

EDIT lire la question mieux, essayez ceci:

SELECT 
    d.YourDate 
     ,SUM(dt.CountOf) AS CountOf 
    FROM (SELECT 
       LEFT(CONVERT(char(23),YourDate,121),10) AS Date 
        ,COUNT(*) AS CountOf 
       FROM YourTable 
       GROUP BY LEFT(CONVERT(char(23),YourDate,121),10) 
     ) dt 
     INNER JOIN (SELECT 
         DISTINCT LEFT(CONVERT(char(23),YourDate,121),10) AS Date 
         FROM YourTable 
        ) d ON dt.Date<=LEFT(CONVERT(char(23),d.YourDate,121),10) 
    GROUP BY d.YourDate 
    ORDER BY d.YourDate 
+0

Cela va donner compte par jour, ne compte pas de toutes les choses avant le jour un jour donné. –

+0

@Russell Steen, merci, j'ai mieux lu la question, voir edit fait ce que l'OP veut. –

0
SELECT Count(*), LEFT(CONVERT(char(23),YourDate,121),10) AS Date FROM 
(SELECT 
    DISTINCT LEFT(CONVERT(char(23),YourDate,121),10) AS Date 
    FROM YourTable 
    GROUP BY LEFT(CONVERT(char(23),YourDate,121),10)) x //Gets the distinct dates. 
INNER JOIN YourTable y on x.Date >= y.Date 
GROUP BY LEFT(CONVERT(char(23),YourDate,121),10) 

Il va être lent. Vraiment vraiment lent. Je déteste penser à ce que seraient les temps de course.

+0

// n'est pas un commentaire tsql, utilisez - –

+0

votre version est lente, il a fallu 1:19 pour retourner 2,402 lignes à partir d'une table de 368,449, où le mien a pris 2 secondes pour retourner 2043 lignes. votre version est des rapports un jour de congé (le compte indiqué est pour la date précédente) et vous manquez le dernier jour. –

+0

J'ai utilisé // sous l'impression erronée qu'il apparaîtrait vert dans l'affichage de stackoverflow. Je sais que ma version est lente. Vos modifications n'étaient pas en place lorsque je l'écrivais et j'essayais de le faire avancer sur la requête. Votre version semble bonne après les modifications. –

1

Je recommande une solution de 2 requêtes. C'est lent, mais j'utilise cette méthode presque tous les jours. L'important est de ne pas rejoindre les 2 tables de la première requête. Vous voulez la duplication de chaque commande pour chaque date dans votre table de recherche.

Vous aurez besoin d'une table de recherche avec 1 ligne pour chaque date de la période qui vous intéresse. Appelons-la dboDateLookup. Voici ce qu'il va ressembler à:

DtIndex 
2009-05-15 
2009-05-16 
2009-05-17 
2009-05-18 
2009-05-19 

Supposons aussi le tableau de commande, dboOrders a 2 colonnes, et numéro de commande OrderDate.

ordernumber    orderdate 
2009-05-15 13:31:47.713 1 
2009-05-15 22:09:32.227 2 
2009-05-16 02:38:36.027 3 
2009-05-16 12:06:49.743 4 
2009-05-16 16:20:26.680 5 

Query1:

SELECT 
Format([ordernumber],"yyyy-mm-dd") AS ByDate, 
ordernumber, 
(If Format([orderdate],"yyyy-mm-dd")<=[DtIndex],1,0) AS NumOrdersBefore 
FROM [dboOrders], [dboDateLookUp]; 

Query2:

Select 
[ByDate], 
sum([NumOrdersBefore]) as RunningTotal 
from [Query1]; 
+0

_FORMAT() _ n'est pas une commande ou une fonction tsql –

0

J'en ai un autre Il n'est pas si fantaisiste Je l'ai couru sur Access donc la syntaxe peut différer un peu. Mais cela semble fonctionner.

P.S.Im relativement nouveau à SQL

données:

ID F1 F2 
1 15/05/2009 13:31:47.713 
2 15/05/2009 22:09:32.227 
3 16/05/2009 02:38:36.027 
4 16/05/2009 12:06:49.743 
5 16/05/2009 16:20:26.680 
6 17/05/2009 01:36:19.480 
7 18/05/2009 09:44:46.993 
8 18/05/2009 14:06:12.073 
9 18/05/2009 15:25:47.540 
10 19/05/2009 10:28:24.150 

Requête:

SELECT Table1.F1 AS Dates, SUM(REPLACE(Len(Table1.F2), Len(Table1.F2), 1)) AS Occurred 
FROM Table1 
GROUP BY Table1.F1; 

Résultat:

Dates Occurred 
15/05/2009 2 
16/05/2009 3 
17/05/2009 1 
18/05/2009 3 
19/05/2009 1 
Questions connexes