Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

SQL сървър за съединяване на таблици и завъртане

Това трябва да работи:

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
;

Или алтернативно:

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
;

Те имат еднакъв набор от резултати и всъщност могат да бъдат третирани по същия начин от оптимизатора на заявки, но вероятно не. Голямата разлика се проявява, когато започнете да поставяте условия на Sale таблица—трябва да тествате и да видите коя заявка работи по-добре.

Забележка:това е от решаващо значение, когато използвате PIVOT че са налични само колоните, които трябва да бъдат част от резултантния изход. Ето защо горните две заявки имат допълнителни извлечени подзаявки за таблица (SELECT ...) така че да се показват само определени колони. Всички колони, които са налични за преглед от PIVOT които не са изброени в обобщения израз, имплицитно ще бъдат групирани и включени в крайния изход. Това вероятно няма да е това, което искате.

Мога ли обаче да ви предложа да направите завъртането в презентационния слой? Ако, например, използвате SSRS, е доста лесно да използвате матричен контрол, който ще извърши цялото завъртане вместо вас. Това е най-добре, защото тогава, ако добавите нова Category , няма да трябва да променяте целия си SQL код!

Има начин за динамично намиране на имената на колоните за завъртане, но той включва динамичен SQL. Аз също не препоръчвам това като най-добрия начин, въпреки че е възможно.

Друг начин, който може работата би била да се обработи предварително тази заявка – което означава да се зададе тригер на Category таблица, която пренаписва изглед, за да съдържа всички съществуващи категории, които съществуват. Това решава много от другите проблеми, които споменах, но отново, използването на презентационния слой е най-добро.

Забележка :Ако имената на вашите колони (които преди бяха стойности) имат интервали, са числа или започват с число, или по друг начин не са валидни идентификатори, трябва да ги поставите в кавички с квадратни скоби, както в PIVOT (Max(Value) FOR CategoryId IN ([1], [2], [3], [4])) P . Като алтернатива можете да промените стойностите, преди да стигнат до PIVOT част от заявката за добавяне на някои букви или премахване на интервали, така че списъкът с колони да не се нуждае от екраниране. За повече информация относно това вижте правилата за идентификатори в 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. Изпълнение на COUNT SQL функция

  2. По-добър начин да проверите дали данните вече съществуват и да ги вмъкнете

  3. Как да върнете всички ненадеждни ограничения CHECK в SQL Server (пример за T-SQL)

  4. Прилагане на агрегатната функция MIN към поле BIT

  5. SQL Server 2008 - АКО НЕ СЪЩЕСТВУВА, ВМЪКНЕТЕ ДРУГА АКТУАЛИЗАЦИЯ