SQL транспонирует сумму поля в столбцы

#sql #sql-server #transpose

#sql #sql-сервер #транспонировать

Вопрос:

Из всех вопросов о транспонировании SQL с использованием PIVOT и UNPIVOT я еще не видел ни одного, в котором вы транспонируете одну строку в столбцы. Это мой запрос:

 SELECT '' as Status, '' as "Count", sum(Created) as "Created", 
sum(Forwarded) as "Forwarded", sum(Replied) as "Replied"
FROM 
   (
      SELECT 
      CASE WHEN a.TO_WG_ID is null and a.CREATED_DATE_TIME =                          
         (select min(b.created_date_time) from ymtn.message b 
         where b.thread_id = a.thread_id) THEN 1 ELSE 0
       END AS "Created",
       CASE WHEN a.TO_WG_ID is not null and a.FROM_WG_ID is not null THEN 1 ELSE 0
       END AS "Forwarded",
       CASE WHEN a.TO_WG_ID is null and a.CREATED_DATE_TIME != (select 
         min(b.created_date_time) from ymtn.message b where b.thread_id =
         a.thread_id) THEN 1 ELSE 0
       END AS "Replied"
       FROM ymtn.MESSAGE a left join YMTN.WORKGROUP b
       ON a.FROM_WG_ID=b.WORKGROUP_ID where b.WORKGROUP_ID='1STOP_PROCESS' 
) a 
  

и это мой вывод из приведенного выше запроса (с двумя статическими полями — Status и Count — которые мне могут не понадобиться, если я смогу просто правильно его перенести):

 Status    Count    Created    Forwarded    Replied
                     1693        209        1499 
  

Это мой желаемый результат:

 Status    Count
Created   1693
Forwarded  209
Replied   1499
  

Пожалуйста, помогите мне найти способ сделать это. Спасибо!

Ответ №1:

Тестовые данные

 DECLARE @TABLE TABLE
 (  [Status] VARCHAR(10)
    ,[Count] VARCHAR(10)
    ,Created INT
    ,Forwarded INT
    ,Replied INT
  )
INSERT INTO @TABLE VALUES
('', '', 1693 , 209 ,1499)
  

Запрос

  ;WITH CTE
 AS
  (
   SELECT * FROM (
      SELECT Created, Forwarded, Replied FROM @TABLE  --<-- Your Existing query here
    ) t
   UNPIVOT (Vals FOR N IN (Created, Forwarded, Replied)) up
  )
SELECT N AS [Status] 
      ,Vals AS [Count]
 FROM CTE
  

Набор результатов

 ╔═══════════╦═══════╗
║  Status   ║ Count ║
╠═══════════╬═══════╣
║ Created   ║  1693 ║
║ Forwarded ║   209 ║
║ Replied   ║  1499 ║
╚═══════════╩═══════╝
  

Ответ №2:

Вы могли бы просто объединить их.

 Select 'Created' as Status, Sum... as Count
from...
union all
select 'Forwarded', Som...
union all
select 'Replied, sum...
  

Ответ №3:

Есть ли необходимость выполнять сложное транспонирование? Я думаю, вы можете использовать объединения, чтобы дать вам то, что вы хотите.

   SELECT
    "Created" AS Status,
    COUNT(*) AS Count
  FROM ymtn.MESSAGE a
  LEFT JOIN YMTN.WORKGROUP b
    ON a.FROM_WG_ID = b.WORKGROUP_ID
  WHERE b.WORKGROUP_ID = '1STOP_PROCESS'
  AND a.TO_WG_ID IS NULL
  AND a.CREATED_DATE_TIME = (SELECT
    MIN(c.created_date_time)
  FROM ymtn.message c
  WHERE c.thread_id = a.thread_id)
  UNION
  SELECT
    "Forwarded",
    COUNT(*)
  FROM ymtn.MESSAGE a
  LEFT JOIN YMTN.WORKGROUP b
    ON a.FROM_WG_ID = b.WORKGROUP_ID
  WHERE b.WORKGROUP_ID = '1STOP_PROCESS'
  AND a.TO_WG_ID IS NOT NULL
  AND a.FROM_WG_ID IS NOT NULL
  UNION
  SELECT
    "Replied",
    COUNT(*)
  FROM ymtn.MESSAGE a
  LEFT JOIN YMTN.WORKGROUP b
    ON a.FROM_WG_ID = b.WORKGROUP_ID
  WHERE b.WORKGROUP_ID = '1STOP_PROCESS'
  AND a.TO_WG_ID IS NULL
  AND a.CREATED_DATE_TIME != (SELECT
    MIN(c.created_date_time)
  FROM ymtn.message c
  WHERE c.thread_id = a.thread_id)
  

(Примечание: образцы таблиц и данных не были предоставлены, поэтому SQL не выполняется для тестирования).