Soy muy nuevo en SQL.
Tengo una mesa como esta:
ID | TeamID | UserID | ElementID | PhaseID | Effort
-----------------------------------------------------
1 | 1 | 1 | 3 | 5 | 6.74
2 | 1 | 1 | 3 | 6 | 8.25
3 | 1 | 1 | 4 | 1 | 2.23
4 | 1 | 1 | 4 | 5 | 6.8
5 | 1 | 1 | 4 | 6 | 1.5
Y me dijeron que obtuviera datos como este
ElementID | PhaseID1 | PhaseID5 | PhaseID6
--------------------------------------------
3 | NULL | 6.74 | 8.25
4 | 2.23 | 6.8 | 1.5
Entiendo que necesito usar la función PIVOT. Pero no puedo entenderlo con claridad. Sería de gran ayuda si alguien pudiera explicarlo en el caso anterior (o cualquier alternativa, si corresponde).
sql-server
sql-server-2008
tsql
pivot
Nosotros somos
fuente
fuente
PhaseID
antes de QUOTENAME. ¿Correcto?SELECT distinct '],['
, y también al final de la declaración1, 2, '') + ']'
Estos son el ejemplo de pivote muy básico, por favor revise eso.
SQL SERVER - Ejemplos de tablas PIVOT y UNPIVOT
Ejemplo del enlace anterior para la tabla de productos:
SELECT PRODUCT, FRED, KATE FROM ( SELECT CUST, PRODUCT, QTY FROM Product) up PIVOT (SUM(QTY) FOR CUST IN (FRED, KATE)) AS pvt ORDER BY PRODUCT
rinde:
PRODUCT FRED KATE -------------------- BEER 24 12 MILK 3 1 SODA NULL 6 VEG NULL 5
Se pueden encontrar ejemplos similares en la publicación del blog Tablas dinámicas en SQL Server. Una simple muestra
fuente
SELECT CUST, VEG, SODA FROM (SELECT rand() as x, CUST, PRODUCT, QTY FROM Product) up PIVOT ( SUM(x) FOR PRODUCT IN (VEG, SODA) ) AS pvt ORDER BY CUST GO
Para que esto funcione, debe eliminar laqty
columna de la fuenteTengo algo que agregar aquí que nadie mencionó.
La
pivot
función funciona muy bien cuando la fuente tiene 3 columnas: una para elaggregate
, otra para distribuir como columnasfor
y otra como pivote para larow
distribución. En el ejemplo de producto esQTY, CUST, PRODUCT
.Sin embargo, si tiene más columnas en la fuente, dividirá los resultados en varias filas en lugar de una fila por pivote en función de valores únicos por columna adicional (como
Group By
lo haría en una consulta simple).Vea este ejemplo, he agregado una columna de marca de tiempo a la tabla de origen:
Ahora mira su impacto:
SELECT CUST, MILK FROM Product -- FROM (SELECT CUST, Product, QTY FROM PRODUCT) p PIVOT ( SUM(QTY) FOR PRODUCT IN (MILK) ) AS pvt ORDER BY CUST
Para solucionar este problema, puede extraer una subconsulta como fuente como todos han hecho anteriormente, con solo 3 columnas (esto no siempre funcionará para su escenario, imagine si necesita poner un
where
condición para la marca de tiempo).La segunda solución es usar ay
group by
hacer una suma de los valores de la columna pivotada nuevamente.SELECT CUST, sum(MILK) t_MILK FROM Product PIVOT ( SUM(QTY) FOR PRODUCT IN (MILK) ) AS pvt GROUP BY CUST ORDER BY CUST GO
fuente
Un pivote se usa para convertir una de las columnas en su conjunto de datos de filas en columnas (esto generalmente se conoce como la columna de expansión ). En el ejemplo que ha dado, esto significa convertir las
PhaseID
filas en un conjunto de columnas, donde hay una columna para cada valor distinto quePhaseID
puede contener: 1, 5 y 6 en este caso.Estos valores pivotados se agrupan a través de la
ElementID
columna del ejemplo que ha proporcionado.Por lo general, también debe proporcionar alguna forma de agregación que le proporcione los valores a los que hace referencia la intersección del valor de propagación (
PhaseID
) y el valor de agrupación (ElementID
). Aunque en el ejemplo dado, la agregación que se utilizará no está clara, pero involucra laEffort
columna.Una vez que se realiza este pivote, las columnas de agrupación y distribución se utilizan para encontrar un valor de agregación . O en su caso,
ElementID
yPhaseIDX
busqueEffort
.Al utilizar la terminología de agrupación, difusión y agregación , normalmente verá una sintaxis de ejemplo para un pivote como:
WITH PivotData AS ( SELECT <grouping column> , <spreading column> , <aggregation column> FROM <source table> ) SELECT <grouping column>, <distinct spreading values> FROM PivotData PIVOT (<aggregation function>(<aggregation column>) FOR <spreading column> IN <distinct spreading values>));
Esto brinda una explicación gráfica de cómo las columnas de agrupación, distribución y agregación se convierten de la fuente a tablas dinámicas si eso ayuda aún más.
fuente
Para configurar el error de compatibilidad
use esto antes de usar la función pivote
ALTER DATABASE [dbname] SET COMPATIBILITY_LEVEL = 100
fuente
SELECT <non-pivoted column>, [first pivoted column] AS <column name>, [second pivoted column] AS <column name>, ... [last pivoted column] AS <column name> FROM (<SELECT query that produces the data>) AS <alias for the source query> PIVOT ( <aggregation function>(<column being aggregated>) FOR [<column that contains the values that will become column headers>] IN ( [first pivoted column], [second pivoted column], ... [last pivoted column]) ) AS <alias for the pivot table> <optional ORDER BY clause>; USE AdventureWorks2008R2 ; GO SELECT DaysToManufacture, AVG(StandardCost) AS AverageCost FROM Production.Product GROUP BY DaysToManufacture; DaysToManufacture AverageCost 0 5.0885 1 223.88 2 359.1082 4 949.4105 -- Pivot table with one row and five columns SELECT 'AverageCost' AS Cost_Sorted_By_Production_Days, [0], [1], [2], [3], [4] FROM (SELECT DaysToManufacture, StandardCost FROM Production.Product) AS SourceTable PIVOT ( AVG(StandardCost) FOR DaysToManufacture IN ([0], [1], [2], [3], [4]) ) AS PivotTable; Here is the result set. Cost_Sorted_By_Production_Days 0 1 2 3 4 AverageCost 5.0885 223.88 359.1082 NULL 949.4105
fuente
<SELECT query that produces the data>
mesa no es justa?