Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Serwer SQL łączy tabele i przestawiaj

To powinno działać:

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
;

Lub alternatywnie:

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
;

Mają one ten sam zestaw wyników i w rzeczywistości mogą być traktowane tak samo przez optymalizator zapytań, ale prawdopodobnie nie. Duża różnica pojawia się, gdy zaczynasz stawiać warunki na Sale table — powinieneś przetestować i zobaczyć, które zapytanie działa lepiej.

Uwaga:ma to kluczowe znaczenie podczas korzystania z PIVOT że dostępne są tylko kolumny, które powinny być częścią wynikowego wyniku. Dlatego te dwa powyższe zapytania zawierają dodatkowe podzapytania w tabeli pochodnej (SELECT ...) tak, że widoczne są tylko określone kolumny. Wszystkie kolumny, które są dostępne dla PIVOT które nie są wymienione w wyrażeniu przestawnym, zostaną niejawnie zgrupowane i uwzględnione w ostatecznym wyniku. To prawdopodobnie nie będzie to, czego chcesz.

Czy mogę jednak zasugerować, abyś wykonał przechylanie w warstwie prezentacji? Jeśli, na przykład, używasz SSRS, całkiem łatwo jest użyć kontrolki matrycy, która wykona za Ciebie całą zmianę. Tak jest najlepiej, ponieważ wtedy, jeśli dodasz nową Category , nie będziesz musiał modyfikować całego kodu SQL!

Istnieje sposób na dynamiczne znalezienie nazw kolumn do przestawienia, ale wymaga to dynamicznego SQL. Naprawdę nie polecam tego jako najlepszego sposobu, chociaż jest to możliwe.

Kolejny sposób może praca polegałaby na wstępnym przetworzeniu tego zapytania — co oznacza ustawienie wyzwalacza dla Category tabela, która przepisuje widok tak, aby zawierał wszystkie istniejące kategorie. To rozwiązuje wiele innych problemów, o których wspomniałem, ale znowu najlepiej jest używać warstwy prezentacji.

Uwaga :Jeśli nazwy kolumn (które były poprzednio wartościami) mają spacje, są liczbami lub zaczynają się od liczby lub w inny sposób nie są prawidłowymi identyfikatorami, należy je zacytować w nawiasach kwadratowych, jak w PIVOT (Max(Value) FOR CategoryId IN ([1], [2], [3], [4])) P . Alternatywnie możesz zmodyfikować wartości, zanim dotrą do PIVOT część zapytania, aby poprzedzić niektóre litery lub usunąć spacje, aby lista kolumn nie wymagała ucieczki. Aby dowiedzieć się więcej na ten temat, zapoznaj się z zasadami dotyczącymi identyfikatorów w SQL Server.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Przykłady COS() w SQL Server

  2. Baza danych kopii zapasowych SQL Server Express | Jak zaplanować automatyzację i czyszczenie kopii zapasowej SQL Express

  3. Jak wdrożyć SQL Server Compact Edition 4.0?

  4. jak podzielić łańcuch na spację w SQL

  5. Jak używać if..else w przepływie danych na podstawie wartości zmiennych użytkownika w SSIS