Search code examples
sqlt-sqlcasesql-server-2014

SQL 2014 - amalgamating rows into single row, multiple columns with CASE statements


SQL Server 2014 using T-SQL.

In our database, customers have issues(!) and each issue assigned against a customer has a separate row in the table I'm querying.

I'm looking to create an single row for each of these issues (along with some other information) but at the moment, each of my CASE statements is creating a single row.

So the output is current like this (I've changed some header names so they fit on here):

Prod    Date        Time    Cust    Lname   Fname   Street 1          S2    City            Zip     Email               CSI     Action  Dog Prog    TourHeadsets
Tosca   08-Apr-17   2:30 PM 122253  Smith   Michael 33 Rodeo Drive    NULL  Beverley Hills  90210   msmith@email.com    NULL    NULL    0   None    0   1
Tosca   08-Apr-17   2:30 PM 122253  Smith   Michael 33 Rodeo Drive    NULL  Beverley Hills  90210   msmith@email.com    NULL    NULL    0   Large   0   0
Tosca   08-Apr-17   2:30 PM 122253  Smith   Michael 33 Rodeo Drive    NULL  Beverley Hills  90210   msmith@email.com    NULL    NULL    0   None    2   0
Tosca   08-Apr-17   2:30 PM 125634  Brown   Sarah   22 Victory Drive  NULL  Beverley Hills  90210   sbrown@email.com    NULL    NULL    0   Large   0   0
Tosca   08-Apr-17   2:30 PM 125634  Brown   Sarah   22 Victory Drive  NULL  Beverley Hills  90210   sbrown@email.com    NULL    NULL    0   None    2   0
Tosca   08-Apr-17   2:30 PM 125634  Brown   Sarah   22 Victory Drive  NULL  Beverley Hills  90210   sbrown@email.com    NULL    NULL    0   None    0   2

But I'd like this (with the result of the 4 CASE statements in separate columns in the same row):

Prod Date       Time    Cust    Lname   Fname   Street 1         S2  City   Zip Email   CSI Action  Dog Prog    Tour    Headsets
Tosca   08-Apr-17   2:30 PM 122253  Smith   Michael 33 Rodeo Drive   NULL   Beverley Hills  90210   msmith@email.com    NULL    NULL    0   Large print 2   1
Tosca   08-Apr-17   2:30 PM 125634  Brown   Sarah   22 Victory Drive NULL   Beverley Hills  90210   sbrown@email.com    NULL    NULL    0   Large print 2   2

Any help for a rookie?! (Any other feedback on the code very welcome too. I'm totally new to this.) Here's the code I've been using to get this far:

USE impresario
    SELECT 
    g.description AS 'Production'
    ,CONVERT(varchar,f.perf_dt,106) AS 'Date'
    ,FORMAT(CAST(f.perf_dt AS DATETIME),'h:mm tt') AS 'Time'
    ,a.customer_no AS 'Customer'
    ,b.lname AS 'Last name'
    ,b.fname AS 'First name'
    ,c.street1 AS 'Street 1'
    ,c.street2 AS 'Street 2'
    ,c.city AS 'City'
    ,c.postal_code AS 'Postal code'
    ,d.address
    ,a.notes AS 'CSI notes' 
    ,e.notes AS 'Action notes'
    ,CASE h.id
       WHEN 14 THEN '1'
       WHEN 15 THEN '2'
       ELSE '0'
       END
       AS 'Dogs'
    ,CASE h.id
       WHEN 16 THEN 'Large print'
       WHEN 17 THEN 'Braille'
       ELSE 'None'
       END
       AS 'Programmes'
    ,CASE h.id
       WHEN 18 THEN '1'
       WHEN 19 THEN '2'
       ELSE '0'
       END
       AS 'Touch tour'
    ,CASE h.id
       WHEN 20 THEN '1'
       WHEN 21 THEN '2'
       ELSE '0'
       END
       AS 'Headsets'
      FROM T_CUST_ACTIVITY a
      JOIN T_CUSTOMER b ON b.customer_no=a.customer_no
      JOIN T_ADDRESS c ON c.customer_no=a.customer_no
      JOIN T_EADDRESS d ON d.customer_no=a.customer_no
      JOIN T_ISSUE_ACTION e ON e.activity_no=a.activity_no
      JOIN T_PERF f ON f.perf_no=a.perf_no
      JOIN T_INVENTORY g ON g.inv_no=f.prod_season_no
      JOIN TR_ACTION h ON h.id=e.action
      WHERE a.activity_type=21 --'Access requirements' from TR_CUST_ACTIVITY_TYPE
      AND c.primary_ind='Y' --Primary addresses only
      AND d.primary_ind='Y' --Primary emails only
      AND e.action IN 
      (
       14 --Dog x1
      ,15 --Dog x2
      ,16 --Programme (large print)
      ,17 --Programme (braille)
      ,18 --Touch tour x1
      ,19 --Touch tour x2
      ,20 --Headset x1
      ,21 --Headset x2
      )
      ORDER BY f.perf_dt, a.customer_no ASC

Solution

  • I found a way to solve this using MAX against each of the CASE statements, which appears to have worked:

    USE impresario
    SELECT 
    g.description AS 'Production'
    ,CONVERT(varchar,f.perf_dt,106) AS 'Date'
    ,FORMAT(CAST(f.perf_dt AS DATETIME),'h:mm tt') AS 'Time'
    ,a.customer_no AS 'Customer'
    ,b.lname AS 'Last name'
    ,b.fname AS 'First name'
    ,c.street1 AS 'Street 1'
    ,c.street2 AS 'Street 2'
    ,c.city AS 'City'
    ,c.postal_code AS 'Postal code'
    ,d.address
    ,a.notes AS 'CSI notes' 
    ,e.notes AS 'Action notes'
    ,MAX(CASE h.id
       WHEN 14 THEN '1'
       WHEN 15 THEN '2'
       ELSE '0'
       END)
       AS 'Dogs'
    ,MAX(CASE h.id
       WHEN 16 THEN 'Large print'
       WHEN 17 THEN 'Braille'
       ELSE 'None'
       END)
       AS 'Programmes'
    ,MAX(CASE h.id
       WHEN 18 THEN '1'
       WHEN 19 THEN '2'
       ELSE '0'
       END)
       AS 'Touch tour'
    ,MAX(CASE h.id
       WHEN 20 THEN '1'
       WHEN 21 THEN '2'
       ELSE '0'
       END)
       AS 'Headsets'
      FROM T_CUST_ACTIVITY a
      JOIN T_CUSTOMER b ON b.customer_no=a.customer_no
      JOIN T_ADDRESS c ON c.customer_no=a.customer_no
      JOIN T_EADDRESS d ON d.customer_no=a.customer_no
      JOIN T_ISSUE_ACTION e ON e.activity_no=a.activity_no
      JOIN T_PERF f ON f.perf_no=a.perf_no
      JOIN T_INVENTORY g ON g.inv_no=f.prod_season_no
      JOIN TR_ACTION h ON h.id=e.action
      WHERE a.activity_type=21 --'Access requirements' from TR_CUST_ACTIVITY_TYPE
      AND c.primary_ind='Y' --Primary addresses only
      AND d.primary_ind='Y' --Primary emails only
      AND e.action IN 
      (
       14 --Dog x1
      ,15 --Dog x2
      ,16 --Programme (large print)
      ,17 --Programme (braille)
      ,18 --Touch tour x1
      ,19 --Touch tour x2
      ,20 --Headset x1
      ,21 --Headset x2
      )
      GROUP BY 
      g.description
      , f.perf_dt
      , a.customer_no
      , b.lname
      , b.fname
      , c.street1
      , c.street2
      , c.city
      , c.postal_code
      , d.address
      , a.notes
      , e.notes
      ORDER BY 
      f.perf_dt
      , a.customer_no ASC