sql >> Databasteknik >  >> RDS >> Sqlserver

SQL-server anslut tabeller och pivot

Detta borde fungera:

WITH Sales AS (
   SELECT
      S.SaleID,
      S.SoldBy,
      S.SalePrice,
      S.Margin,
      S.Date,
      I.SalePrice,
      I.Category
   FROM
      dbo.Sale S
      INNER JOIN dbo.SaleItem I
         ON S.SaleID = I.SaleID
)
SELECT *
FROM
   Sales
   PIVOT (Max(SalePrice) FOR Category IN (Books, Printing, DVD)) P
;

Eller alternativt:

SELECT
   S.SaleID,
   S.SoldBy,
   S.SalePrice,
   S.Margin,
   S.Date,
   I.Books,
   I.Printing,
   I.DVD
FROM
   dbo.Sale S
   INNER JOIN (
      SELECT *
      FROM
         (SELECT SaleID, SalePrice, Category FROM dbo.SaleItem) I
         PIVOT (Max(SalePrice) FOR Category IN (Books, Printing, DVD)) P
   ) I ON S.SaleID = I.SaleID
;

Dessa har samma resultatuppsättning och kan faktiskt behandlas på samma sätt av frågeoptimeraren, men möjligen inte. Den stora skillnaden spelar in när du börjar sätta villkor på Sale tabell – du bör testa och se vilken fråga som fungerar bäst.

Obs:det är avgörande när du använder PIVOT att endast de kolumner som ska ingå i resultatet är tillgängliga. Det är därför de två ovanstående frågorna har extra härledda tabellunderfrågor (SELECT ...) så att endast specifika kolumner exponeras. Alla kolumner som är tillgängliga för att ses av PIVOT som inte är listade i pivotuttrycket kommer implicit att grupperas på och inkluderas i den slutliga utmatningen. Detta kommer förmodligen inte att vara vad du vill ha.

Får jag dock föreslå att du gör svängningen i presentationslagret? Om du till exempel använder SSRS är det ganska enkelt att använda en matriskontroll som gör all svängning åt dig. Det är bäst, för då lägger du till en ny Category , kommer du inte att behöva ändra all din SQL-kod!

Det finns ett sätt att dynamiskt hitta kolumnnamnen att pivotera, men det involverar dynamisk SQL. Jag rekommenderar inte det som det bästa sättet heller, även om det är möjligt.

Ett annat sätt som kunde arbetet skulle vara att förbehandla den här frågan – vilket betyder att ställa in en utlösare på Category tabell som skriver om en vy för att innehålla alla befintliga kategorier som finns. Detta löser många av de andra problemen jag har nämnt, men återigen, det är bäst att använda presentationslagret.

Obs :Om dina kolumnnamn (som tidigare var värden) har mellanslag, är siffror eller börjar med ett nummer, eller på annat sätt inte är giltiga identifierare, måste du citera dem med hakparenteser som i PIVOT (Max(Value) FOR CategoryId IN ([1], [2], [3], [4])) P . Alternativt kan du ändra värdena innan de når PIVOT del av frågan för att lägga till några bokstäver eller ta bort mellanslag, så att kolumnlistan inte behöver escape. För ytterligare läsning om detta, kolla in reglerna för identifierare i SQL Server.




  1. CAST vs ssis dataflöde implicit konverteringsskillnad

  2. Hur mycket lagringsutrymme används med en varchar(100)-deklaration i mysql?

  3. mysql workbench records limit

  4. mysql skiftlägeskänslig i utf8_general_ci