2017-08-27 4 views
1

Ich habe zwei Tabellen wie folgt aus:Fasst Untergruppen mit SQL

| SalesId | SalesDate | SalesStore |   | StoreId | Name | 
|---------|-----------|------------|   |---------|---------| 
| 1 | 5/3/17 |  3  |   | 1 | Store A | 
| 2 | 2/2/18 |  3  |   | 2 | Store B | 
| 3 | 6/6/17 |  2  |   | 3 | Store C | 
| 4 | 7/8/17 |  3  | 

Ich mag würde wissen, ob es möglich ist, nur die folgende Ausgabe mit SQL zu generieren:

| Year | Store A | Store B | Store C | 
|---------|---------|---------|---------| 
| 2017 | 0 | 1 | 2 | 
| 2018 | 0 | 0 | 1 | 

Grundsätzlich möchte ich die Summe von Verkäufen jedes Geschäftes nach Jahr.

konnte ich die Summe aller Geschäfte bekommen mit:

SELECT YEAR(SalesDate) [Year], Count(1) [Sales Count] 
FROM Sales 
GROUP BY YEAR(SalesDate) 
ORDER BY 1 

Aber ich würde gerne wissen, ob es möglich ist, diese mit einer einzigen SQL-Abfrage zu tun.

+1

Wahrscheinlich müssen Sie über PIVOT Abfragen lesen –

+1

Sie möchten PIVOT oder dynamische Pivot, wenn die Anzahl der SalesStores nicht behoben ist. Viele Antworten finden Sie hier. – Serg

+1

Wenn es sich um eine feste Anzahl von Speichern handelt, kann dies durch bedingte Aggregation erfolgen. Wenn nicht, wie die Leute vor mir sagten, ist PIVOT der richtige Weg. – sagi

Antwort

1

Hier ist eine dynamische Kreuztabellen-Lösung, die eine beliebige Anzahl von Geschäften behandelt ...

IF OBJECT_ID('tempdb..#Store', 'U') IS NOT NULL 
DROP TABLE #Store; 

CREATE TABLE #Store (
    StoreId INT NOT NULL PRIMARY KEY, 
    StoreName CHAR(7) NOT NULL 
    ); 
INSERT #Store (StoreId, StoreName) VALUES (1, 'Store A'), (2, 'Store B'), (3, 'Store C'); 

IF OBJECT_ID('tempdb..#Sales', 'U') IS NOT NULL 
DROP TABLE #Sales; 

CREATE TABLE #Sales (
    SalesId INT NOT NULL PRIMARY KEY, 
    SalesDate DATE NOT NULL, 
    SalesStore INT NOT NULL 
    ); 
INSERT #Sales (SalesId, SalesDate, SalesStore) VALUES 
    (1, '2017-05-03', 3), (2, '2018-02-02', 3), 
    (3, '2017-06-06', 2), (4, '2017-07-08', 3); 

--SELECT * FROM #Store st; 
--SELECT * FROM #Sales s; 

--========================================================= 

DECLARE 
    @StoreCols VARCHAR(8000) = '', 
    @sql VARCHAR(8000) = '', 
    @DeBug BIT = 0; 

SELECT 
    @StoreCols = CONCAT(@StoreCols, ', 
    [', st.StoreName, '] = COUNT(CASE WHEN s.SalesStore = ', st.StoreId, ' THEN 1 END)') 
FROM 
    #Store st 
ORDER BY 
    st.StoreId; 

SET @sql = CONCAT(' 
SELECT 
    [Year] = YEAR(s.SalesDate)', 
    @StoreCols, ' 
FROM 
    #Sales s 
GROUP BY 
    YEAR(s.SalesDate);') 

IF @DeBug = 1 
BEGIN 
    PRINT(@sql); 
END 
ELSE 
BEGIN 
    EXEC(@sql); 
END; 

Die Ergebnisse ...

Year  Store A  Store B  Store C 
----------- ----------- ----------- ----------- 
2017  0   1   2 
2018  0   0   1 

HTH, Jason

1

Ich habe es zu arbeiten, indem Sie eine PIVOT Tabelle für jedes Jahr erstellen und dann eine UNION verwenden, um sie zu kombinieren.

SELECT '2017' AS 'Year',[Store A],[Store B],[Store C] 
FROM 
(
    SELECT YEAR(Sales.SalesDate) 'SalesYear',Store.[Name] 
    FROM Sales 
     JOIN Store ON Sales.SalesStore = StoreId 
    WHERE YEAR(Sales.SalesDate) = 2017) AS table2017 
PIVOT 
(
    COUNT(SalesYear) 
    FOR [Name] IN ([Store A],[Store B],[Store C]) 
) AS pivotTable2017 

UNION 

SELECT '2018' AS 'Year',[Store A],[Store B],[Store C] 
FROM 
(
    SELECT YEAR(Sales.SalesDate) 'SalesYear',Store.[Name] 
    FROM Sales 
     JOIN Store ON Sales.SalesStore = StoreId 
    WHERE YEAR(Sales.SalesDate) = 2018)AS table2018 
PIVOT 
(
    COUNT(SalesYear) 
    FOR [Name] IN ([Store A],[Store B],[Store C]) 
) AS pivotTable2018 

ERGEBNISSE

+------+----------+----------+---------+ 
| Year | Store A | Store B | Store C | 
+------+----------+----------+---------+ 
| 2017 | 0  | 1  | 2 | 
| 2018 | 0  | 0  | 1 | 
+------+----------+----------+---------+