Tengo dos mesas como esta:
| 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 |
Me gustaría saber si es posible generar la siguiente salida usando solo SQL:
| Year | Store A | Store B | Store C |
|---------|---------|---------|---------|
| 2017 | 0 | 1 | 2 |
| 2018 | 0 | 0 | 1 |
Básicamente quiero la suma de ventas de cada tienda por año.
Pude obtener el total de todas las tiendas usando:
SELECT YEAR(SalesDate) [Year], Count(1) [Sales Count]
FROM Sales
GROUP BY YEAR(SalesDate)
ORDER BY 1
Pero me gustaría saber si es posible hacerlo utilizando una sola consulta SQL.
Respuestas
1 para la respuesta № 1Aquí hay una solución dinámica de tablas cruzadas que manejará cualquier número de tiendas ...
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;
Los resultados...
Year Store A Store B Store C
----------- ----------- ----------- -----------
2017 0 1 2
2018 0 0 1
HTH, Jason
1 para la respuesta № 2
Lo hice trabajar creando un PIVOT
tabla para cada año y luego utilizando una UNION
para combinarlos.
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
RESULTADOS
+------+----------+----------+---------+
| Year | Store A | Store B | Store C |
+------+----------+----------+---------+
| 2017 | 0 | 1 | 2 |
| 2018 | 0 | 0 | 1 |
+------+----------+----------+---------+