2010-08-11 7 views
3

Salut, je voudrais créer un SQL pour regrouper les enregistrements en fonction de la gammeComment regrouper les enregistrements en fonction de la gamme dans SQL

Par exemple, supposons que je

Number Time   Price 
100 20100810   10.0 
100 20100812   15.0 
160 20100810   10.0 
200 20100810   12.0 
210 20100811   13.0 
300 20100811   14.0 
350 20100810   16.0 

Maintenant, je dois pour obtenir les enregistrements en fonction de la plage du "Nombre": [100,200),[200,300),[300,400) and [0,400]. Pour chaque plage, je dois le « prix » du « Time » lastest

Ainsi, les résultats devraient être

NumberRange   Time   Price 
    1   20100812   15.0 
    2   20100811   13.0 
    3   20100811   14.0 
    4   20100812   15.0 

Comment puis-je construire une instruction SQL pour produire cela?

Je ne travaille pas sur une base de données spécifique. Je ne recherche donc pas d'instruction SQL spécifique à la base de données

+0

Cela peut varier selon la plate-forme. Quel genre de SQL utilisez-vous? – kbrimington

Répondre

4

Utilisation:

SELECT x.rank, x.time, x.price 
    FROM (SELECT *, 
       CASE 
        WHEN number BETWEEN 100 and 199 THEN 1 
        WHEN number BETWEEN 200 and 299 THEN 2 
        WHEN number BETWEEN 300 and 399 THEN 3 
        ELSE NULL 
       END AS rank 
      FROM TABLE) x 
      JOIN (SELECT t.rank, 
         MAX(t.time) AS max_time 
        FROM (SELECT *, 
           CASE 
            WHEN number BETWEEN 100 and 199 THEN 1 
            WHEN number BETWEEN 200 and 299 THEN 2 
            WHEN number BETWEEN 300 and 399 THEN 3 
            ELSE NULL 
           END AS rank 
          FROM TABLE) t 
       GROUP BY t.rank) y ON y.rank = x.rank 
           AND y.max_time = x.time 
UNION ALL 
SELECT x.rank, x.time, x.price 
    FROM (SELECT *, 
       CASE 
       WHEN number BETWEEN 0 and 400 THEN 4 
       ELSE NULL 
       END AS rank 
      FROM TABLE) x 
      JOIN (SELECT t.rank, 
         MAX(t.time) AS max_time 
        FROM (SELECT *, 
           CASE 
           WHEN number BETWEEN 0 and 400 THEN 4 
           ELSE NULL 
           END AS rank 
          FROM TABLE) t 
       GROUP BY t.rank) y ON y.rank = x.rank 
           AND y.max_time = x.time 
+0

Je definity manqué quelques trucs dans la question originale. Tx pour cette longue réponse. – Tobiasopdenbrouw

0

Travail à domicile?

Vous pouvez sélectionner une colonne supplémentaire avec une instruction if pour déterminer l'ID de plage pertinent. Puis groupez par cette nouvelle colonne.

0

Bien que certains des éléments suivants exige tombent en dehors du noyau standard SQL, ils sont caractéristiques standard SQL complet (par exemple, les constructeurs de ligne sont une pleine fonctionnalité SQL-92, CTEs sont une SQL- complète 99 fonctionnalité, etc), et sera en effet trouvé dans certains produits tels que SQL Server et Oracle:

WITH MyTable (my_Number, my_Time, Price) 
    AS 
    (
     SELECT my_Number, CAST(my_Time AS DATE), 
      CAST(Price AS DECIMAL(5, 2)) 
     FROM (
       VALUES (100, '2010-08-10', 10), 
        (100, '2010-08-12', 15), 
        (160, '2010-08-10', 10), 
        (200, '2010-08-10', 12), 
        (210, '2010-08-11', 13), 
        (300, '2010-08-11', 14), 
        (350, '2010-08-10', 16) 
      ) AS MyTable (my_Number, my_Time, Price) 
    ), Ranges (NumberRange, range_start, range_end) 
    AS 
    (
     SELECT NumberRange, range_start, range_end 
     FROM (
       VALUES (1, 100, 200), 
        (2, 200, 300), 
        (3, 300, 400), 
        (4, 0, 400) 
      ) AS Ranges (NumberRange, range_start, range_end) 
    ), 
    RangesMaxTimes (NumberRange, range_start, range_end, max_time) 
    AS 
    ( 
     SELECT R1.NumberRange, 
      R1.range_start, R1.range_end, 
      MAX(M1.my_Time) AS max_time 
     FROM MyTable AS M1 
     INNER JOIN Ranges AS R1 
      ON R1.range_start <= M1.my_Number 
      AND M1.my_Number < R1.range_end 
     GROUP 
      BY R1.NumberRange, R1.range_start, R1.range_end 
    ) 
SELECT R1.NumberRange, M1.my_Time, M1.Price 
    FROM MyTable AS M1 
     INNER JOIN RangesMaxTimes AS R1 
      ON R1.range_start <= M1.my_Number 
      AND M1.my_Number < R1.range_end 
      AND M1.my_Time = R1.max_time; 
Questions connexes