Domanda

Ho una tabella che attualmente è una lunga lista di dispositivi e informazioni su quando sono stati venduti. Ho bisogno di prendere la tavola che sarebbe simile a questa:

Item   |  Time Sold
--------------------
  A        05/2010
  B        04/2010
  C        03/2010
  A        04/2010
  A        05/2010

E poi ha un tavolo con la voce come prima colonna, con il conteggio delle date che sono le intestazioni delle colonne, come di seguito:

Item   |   Count_03/2010   |  Count_04/2010  |  Count_05/2010
-------------------------------------------------------------
  A    |         0         |         1       |        2
  B    |         0         |         1       |        0
  C    |         1         |         0       |        0

C'è un modo semplice di fare questo? So che in altre lingue v'è un unico comando per farlo, si chiedeva se SQL aveva uno.

Modifica

Il mio problema è che non c'è più di una tabella, e in alcune tabelle dei mesi può essere diverso da quello in altre tabelle. Esiste un modo per scrivere uno script che si applica a tutti loro, ottenendo le variabili elencate e quindi utilizzando quelli di creare le colonne nel codice? Potrei scrivere uno se sapevo che i mesi sarebbero sempre gli stessi, ma dal momento che sono variabili, c'è un modo per farlo.

È stato utile?

Soluzione

SQL Server 2005 e fino ha qualcosa chiamato pivot, ma non è ancora un comando ed è necessario conoscere i valori del tempo venduto colonna. È possibile utilizzare un approccio dinamico pivot come dimostrato da Itzik Ben-Gan nella sua Inside Microsoft SQL Server 2008: T-SQL Interrogazione prenotare

Esempio

create table #test (Item char(1),  TimeSold varchar(20))

  insert #test values('A','05/2010')
  insert #test values('B','04/2010')
  insert #test values('C','03/2010')
  insert #test values('A','04/2010')
  insert #test values('A','05/2010')

  SELECT *
FROM
(SELECT Item,TimeSold
FROM #test) AS pivTemp
PIVOT
(   COUNT(TimeSold)
    FOR TimeSold IN ([05/2010],[04/2010],[03/2010])
) AS pivTable

Altri suggerimenti

non ho la prova, ma il seguente dovrebbe funzionare. I utilizza sottoquery per ottenere i risultati desiderati:

select item, 
(select count(*) from items i where time_sold between '02/2010' AND '03/2010' i.item=item ),
(select count(*) from items i where time_sold between '03/2010' AND '04/2010' i.item=item ),
(select count(*) from items i where time_sold between '04/2010' AND '05/2010' i.item=item )
from items;

nativamente MS-SQL non fornisce alcuna funzionalità per visualizzare i dati nel formato tabellare che si desidera senza conoscere i valori che si desidera generare i nomi delle colonne da.

C'è un grande articolo sulla creazione di query a campi incrociati in modo dinamico in MS-SQL . Si tratta di un hack, ma sembra che dovrebbe funzionare.

In caso contrario, un approccio più flessibile è quello di fare ...

Select Distinct
Item,
Time Sold,
Count([Item])
From
MyTable
Group By
Item,
Time Sold

Questo vi darà:

    Item | Time Sold | Count
    ------------------------
    A    | 05/2010   | 2
    A    | 04/2010   | 1
    B    | 04/2010   | 1
    C    | 03/2010   | 1

Questo è un formato più molto su cui lavorare per l'analisi dei dati, in quanto è possibile scrivere una query per gestire i dati come i nomi delle colonne sono noti.

Ad esempio, è possibile utilizzare questi dati in uno strumento di comunicazione a:

  • Il conte tutti gli articoli venduti
  • Mostra una lista distinta di date
  • Mostra un elenco dei quali date avevano il maggior numero di oggetti venduti

Per arrivare nel formato rapporto hai richiesto, è meglio utilizzare uno strumento di reporting, come Crystal Reports o Excel anche.

Excel e Crystal Report supporto tabelle pivot per la visualizzazione dei dati in formato tabulare di richiedere (e guarderò un bello molto anche!).

È possibile group by per ottenere risultati aggregati per articolo. Utilizzando sum e case, è possibile contare il numero di elementi in un determinato periodo. Ad esempio:

select  item
,       sum(case when time_sold between '02/2010' and '03/2010' then 1 end)
,       sum(case when time_sold between '03/2010' and '04/2010' then 1 end)
,       sum(case when time_sold between '04/2010' and '05/2010' then 1 end)
from    items
group by
        item

Se si dispone di tabelle di origine in diversi formati, li unione insieme in una sottoquery. Mi limiterò questo esempio per una sola gamma per risparmiare spazio:

select  item
,       sum(IsInRange1)
from    (
        select  item
        ,       case when time_sold between '01/2010' and '03/2010' 
                          then 1 end as IsInRange1
        from    usa_items
        union all
        select  item
        ,       case when time_sold in ('gennaio', 'febbraio', 'marzo') 
                          then 1 end
        from    italian_items
        union all
        select  item
        ,       case when time_sold between '2010-01-01' and '2010-03-01' 
                          then 1 end
        from    iso_items
        ) SubqueryAlias
group by
        item
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top