sql >> Databáze >  >> RDS >> Sqlserver

SQL server spojit tabulky a pivot

Mělo by to fungovat:

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
;

Nebo alternativně:

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
;

Ty mají stejnou sadu výsledků a ve skutečnosti s nimi může optimalizátor dotazů zacházet stejně, ale možná ne. Velký rozdíl přichází do hry, když začnete klást podmínky na Sale tabulka – měli byste otestovat a zjistit, který dotaz funguje lépe.

Poznámka:při použití PIVOT je to zásadní že jsou k dispozici pouze sloupce, které by měly být součástí výsledného výstupu. To je důvod, proč mají dva výše uvedené dotazy navíc odvozené poddotazy tabulky (SELECT ...) takže jsou vystaveny pouze konkrétní sloupce. Všechny sloupce, které lze zobrazit pomocí PIVOT které nejsou uvedeny ve výrazu pivot, budou implicitně seskupeny a zahrnuty do konečného výstupu. To pravděpodobně nebude to, co chcete.

Mohu vám však navrhnout, abyste provedli pivotování v prezentační vrstvě? Pokud například používáte SSRS, je docela snadné použít maticové ovládání, které za vás udělá veškeré otáčení. To je nejlepší, protože když přidáte novou Category , nebudete muset upravovat celý svůj kód SQL!

Existuje způsob, jak dynamicky najít názvy sloupců, které se mají pivotovat, ale zahrnuje to dynamické SQL. Ani to opravdu nedoporučuji jako nejlepší způsob, i když je to možné.

Jiný způsob, jak mohl práce by spočívala v předzpracování tohoto dotazu – to znamená nastavení spouštěče pro Category tabulka, která přepisuje pohled tak, aby obsahoval všechny existující kategorie. To řeší spoustu dalších problémů, které jsem zmínil, ale opět je nejlepší použít prezentační vrstvu.

Poznámka :Pokud názvy sloupců (které byly dříve hodnotami) obsahují mezery, jsou to čísla nebo začínají číslem nebo jinak nejsou platnými identifikátory, musíte je citovat v hranatých závorkách jako v PIVOT (Max(Value) FOR CategoryId IN ([1], [2], [3], [4])) P . Případně můžete upravit hodnoty, než se dostanou do PIVOT část dotazu přidat některá písmena nebo odstranit mezery, takže seznam sloupců nepotřebuje escapování. Chcete-li si přečíst další informace, podívejte se na pravidla pro identifikátory na serveru SQL.




  1. Tabulka MySQL Alter, přidejte sloupec s jedinečnou náhodnou hodnotou

  2. SQL Server 2008 R2 uvízl v režimu jednoho uživatele

  3. Jak vrátit odlišné hodnoty a jejich počet?

  4. MySQL:Hledání opakovaných jmen v mé tabulce uživatelů