在同一列中查询3个不同的值

时间:2019-05-30 19:16:35

标签: sql sql-server tsql

我正在努力以所需的格式提取数据,但直到现在仍不成功。

我有下表

id_ticket,date_ticket,office_ticket,status_ticket

我需要查询来返回我,每个月一次,并且总是在同一办公室:

  • 任何状态的票数(COUNT)
  • 状态为5的票数(COUNT)
  • 状态为6的票数(COUNT)
  • 年份

我要返回的查询仅返回具有任何状态的票证总数。奏效了!

SELECT
COUNT (id_ticket) as TotalTicketsPerMonth,
'sYear' = YEAR (date_ticket),
'sMonth' = MONTH (date_ticket)
FROM crm_vw_Tickets
WHERE office_ticket = 1
GROUP BY
YEAR (date_ticket), MONTH (date_ticket)
ORDER BY sYear ASC, sMonth ASC

返回状态为5的票证的总金额

SELECT
COUNT (id_ticket) as TotalTicketsPerMonth,
'sYear' = YEAR (date_ticket),
'sMonth' = MONTH (date_ticket)
FROM crm_vw_Tickets
WHERE office_ticket = 1 AND status_ticket = 5
GROUP BY
YEAR (date_ticket), MONTH (date_ticket)
ORDER BY sYear ASC, sMonth ASC

但是我需要返回的内容类似于:

Year Month Total Status5 Status6
2018   1     15      5        3

2018   2     14      4        5

2018   3     19      2        8

谢谢您的帮助。

2 个答案:

答案 0 :(得分:1)

您很近。您可以使用CASE表达式来获取所需的内容:

SELECT
    COUNT (id_ticket) as TotalTicketsPerMonth,
    SUM(CASE WHEN status_ticket = 5 THEN 1 END) as Status5,
    SUM(CASE WHEN status_ticket = 6 THEN 1 END) as Status6,
    'sYear' = YEAR (date_ticket),
    'sMonth' = MONTH (date_ticket)
FROM crm_vw_Tickets
WHERE office_ticket = 1
GROUP BY YEAR (date_ticket), MONTH (date_ticket)
ORDER BY sYear ASC, sMonth ASC

答案 1 :(得分:0)

以下代码基于JNevill的答案,包括“缺少”月份的摘要行,即没有票据的月份以及有票据的月份。基本思想是创建一个表格,其中包含从第一个票证到最后一个票证的所有月份,outer join票证数据与月份,然后汇总数据。 (计数表数字表日历表或多或少是适用术语。)

这是一个公用表表达式(CTE),其中包含几个查询,这些查询将逐步向结果迈进。您可以通过用注释上方的注释之一替换最终的select语句来查看中间步骤的结果。

-- Sample data.
declare @crm_vw_Tickets as Table ( id_ticket Int Identity, date_ticket Date, office_ticket Int, status_ticket Int );
insert into @crm_vw_Tickets ( date_ticket, office_ticket, status_ticket ) values
  ( '20190305', 1, 6 ), -- Shrove Tuesday.
  ( '20190501', 1, 5 ), -- May Day.
  ( '20190525', 1, 5 ); -- Towel Day.
select * from @crm_vw_Tickets;

-- Summarize the data.
with
  -- Get the minimum and maximum ticket dates for   office_ticket   1.
  Limits as (
    select Min( date_ticket ) as MinDateTicket, Max( date_ticket ) as MaxDateTicket
      from @crm_vw_Tickets
      where office_ticket = 1 ),
  -- 0 to 9.
  Ten ( Number ) as ( select * from ( values (0), (1), (2), (3), (4), (5), (6), (7), (8), (9) ) as Digits( Number ) ),
  -- 100 rows.
  TenUp2 ( Number ) as ( select 42 from Ten as L cross join Ten as R ),
  -- 10000 rows.  We'll assume that 10,000 months should cover the reporting range.
  TenUp4 ( Number ) as ( select 42 from TenUp2 as L cross join TenUp2 as R ),
  -- 1 to the number of months to summarize.
  Numbers ( Number ) as ( select top ( select DateDiff( month, MinDateTicket, MaxDateTicket ) + 1 from Limits ) Row_Number() over ( order by ( select NULL ) ) from TenUp4 ),
  -- Starting date of each month to summarize.
  Months as (
    select DateAdd( month, N.Number - 1, DateAdd( day, 1 - Day( L.MinDateTicket ), L.MinDateTicket ) ) as StartOfMonth
      from Limits as L cross join
        Numbers as N ),
  -- All tickets assigned to the appropriate month and a row with NULL ticket data
  --   for each month without tickets.
  MonthsAndTickets as (
    select M.StartOfMonth, T.*
      from Months as M left outer join
        @crm_vw_Tickets as T on M.StartOfMonth <= T.date_ticket and T.date_ticket < DateAdd( month, 1, M.StartOfMonth ) )
  -- Use one of the following   select   statements to see the intermediate or final results:
  --select * from Limits;
  --select * from Ten;
  --select * from TenUp2;
  --select * from TenUp4;
  --select * from Numbers;
  --select * from Months;
  --select * from MonthsAndTickets;
  select Year( StartOfMonth ) as SummaryYear, Month( StartOfMonth ) as SummaryMonth,
    Count( id_ticket ) as TotalTickets,
    Coalesce( Sum( case when status_ticket = 5 then 1 end ), 0 ) as Status5Tickets,
    Coalesce( Sum( case when status_ticket = 6 then 1 end ), 0 ) as Status6Tickets
    from MonthsAndTickets
    where office_ticket = 1 or office_ticket is NULL -- Handle months with no tickets.
    group by StartOfMonth
    order by StartOfMonth;

请注意,最后的select使用Count( id_ticket )Coalesce并显式检查NULL来产生适当的输出值(0)长达数月之久,票。