2012-07-15 12 views
6

Ho una tabella contenente le colonne date_trans, time_trans, prezzo. Dopo aver selezionato la query, voglio aggiungere una nuova colonna "Conteggio" che sarà calcolata come i valori uguali consecutivi della colonna del prezzo e le righe precedenti che hanno prezzi uguali consecutivi saranno rimosse dal risultato finale. Vedere i risultati attesi:Ottimizza una query o suggerisci equivalente LINQ

date_trans time_trans price **Count**  
2011-02-22 09:39:59 58.02 1 
2011-02-22 09:40:03 58.1 *ROW WILL BE REMOVED 
2011-02-22 09:40:07 58.1 *ROW WILL BE REMOVED 
2011-02-22 09:40:08 58.1 3 
2011-02-22 09:40:10 58.15 1 
2011-02-22 09:40:10 58.1 *ROW WILL BE REMOVED 
2011-02-22 09:40:14 58.1 2 
2011-02-22 09:40:24 58.15 1 
2011-02-22 09:40:24 58.18 *ROW WILL BE REMOVED 
2011-02-22 09:40:24 58.18 *ROW WILL BE REMOVED 
2011-02-22 09:40:24 58.18 3 
2011-02-22 09:40:24 58.15 1 

Si prega di suggerire una query SQL o espressione LINQ per selezionare dalla tabella

Attualmente, posso farlo sia una query di selezione e loop attraverso tutte le righe selezionate, ma quando si seleziona milioni di file ci vogliono ore.

mio codice corrente:

string query = @"SELECT date_trans, time_trans, price 
          FROM tbl_data 
         WHERE date_trans BETWEEN '2011-02-22' AND '2011-10-21' 
         AND time_trans BETWEEN '09:30:00' AND '16:00:00'"; 

      DataTable dt = oUtil.GetDataTable(query); 

      DataColumn col = new DataColumn("Count", typeof(int)); 
      dt.Columns.Add(col); 

      int priceCount = 1; 
      for (int count = 0; count < dt.Rows.Count; count++) 
      { 
       double price = Convert.ToDouble(dt.Rows[count]["price"]); 
       double priceNext = (count == dt.Rows.Count - 1) ? 0 : Convert.ToDouble(dt.Rows[count + 1]["price"]); 
       if (price == priceNext) 
       { 
        priceCount++; 
        dt.Rows.RemoveAt(count); 
        count--; 
       } 
       else 
       { 
        dt.Rows[count]["Count"] = priceCount; 
        priceCount = 1; 
       } 
      } 
+0

Penso che sia possibile con le funzioni analitiche in SQL. È tardi, quindi il mio cervello non è in grado di elaborare tutto ora, ma quando sono a riposo, tornerò e vedrò se hai ancora bisogno di una risposta. Ma penso che dovresti iniziare guardando [questa risposta] (http://stackoverflow.com/questions/7854854/getting-all-consecutive-rows-differing-by-certain-value) e come usa le funzioni analitiche. – Ally

risposta

2

Questo è interessante. Penso che ciò che è necessario sarebbe qualcosa di simile:

SELECT MAX(date_trans), MAX(time_trans), MAX(price), COUNT(*) 
FROM 
    (SELECT *, ROW_NUMBER() OVER(PARTITION BY price ORDER BY date_trans, time_trans) - ROW_NUMBER() OVER(ORDER BY date_trans, time_trans) AS grp 
    FROM transactions) grps 
GROUP BY grp 

trovato la soluzione qui: http://www.sqlmag.com/article/sql-server/solution-to-the-t-sql-puzzle-grouping-consecutive-rows-with-a-common-element

UPDATE colonna

Il raggruppamento deve includere anche "prezzo", altrimenti gruppi non potrebbe essere unico. Un'altra cosa è che la colonna data e ora deve essere combinata in una colonna datetime in modo che il valore massimo datetime sia corretto nei gruppi che iniziano verso la fine di un giorno e terminano all'inizio del successivo. Ecco la query corretta.

SELECT MAX(CAST(date_trans AS DATETIME) + CAST(time_trans AS DATETIME)) , MAX(price), COUNT(*) 
FROM 
    (SELECT *, 
     CAST(ROW_NUMBER() OVER(PARTITION BY price ORDER BY date_trans, time_trans) - ROW_NUMBER() OVER(ORDER BY date_trans, time_trans) AS NVARCHAR(255)) + '-' + CAST(price AS NVARCHAR(255)) AS grp 
    FROM transactions 
    ORDER BY date_trans, time_trans) grps 
GROUP BY grp 

La query potrebbe essere più ottimale con la colonna 'GRP' come matrice di byte o bigint invece di un nvarchar. Inoltre hai citato una colonna 'volume' che probabilmente vuoi sommare all'interno del gruppo.

+0

Grazie, Pawel. Ci sei quasi. Si prega di scaricare il csv, importare nel database e controllare. Alcuni record stanno mostrando duplicati. Per favore aiutami migliorando la tua richiesta. https://docs.google.com/open?id=0B_fUxFgeU2-dc3hfR2JrR2ExQ2s Le colonne sono date_trans, time_trans, prezzo, volume nel diritto CSV – Mainuddin

+0

. Aggiornata la risposta. Non l'avevo notato prima ma hai taggato la tua domanda "mysql" ma intendevi "mssql", giusto? –

+0

OK. Aggiustato. –