使用T-SQL的SQL Server 2014。
在我们的数据库中,客户遇到问题(!),并且针对客户分配的每个问题在我查询的表格中都有一个单独的行。
我希望为每个问题创建一行(以及其他一些信息),但目前,我的每个CASE语句都创建了一行。
所以输出是这样的(我已经改变了一些标题名称,所以它们适合这里):
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
但是我喜欢这个(在同一行的不同列中有4个CASE语句的结果):
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
新手的任何帮助?! (关于代码的任何其他反馈也非常受欢迎。我对此非常陌生。)以下是我用来实现这一目标的代码:
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
答案 0 :(得分:0)
当遇到这类问题时,我会这样做 - 使用子查询或CTE对要组合的项目进行分组。如果没有关于数据模型和边缘情况的更多细节,很难确切地知道您需要什么。 (@CuriousKid在他的评论中给出了一些关于这些案例的提示。)但我对最常见的案例做了假设。
注意,我拿出了不需要的连接并清理了一些可怕的格式。
WITH actions AS
(
SELECT
activity_no,
MAX(CASE e.action WHEN 14 THEN '1' WHEN 15 THEN '2' ELSE null END) AS dogs,
MAX(CASE e.action WHEN 16 THEN 'Large print' WHEN 17 THEN 'Braille' ELSE null END) AS programmes,
MAX(CASE e.action WHEN 20 THEN '1' WHEN 21 THEN '2' ELSE null END AS headsets
MAX(CASE e.action WHEN 18 THEN '1' WHEN 19 THEN '2' ELSE null END) AS tt,
LISTAGG(e.notes, ', ') as notes
FROM T_ISSUE_ACTION e
WHERE 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 activity_no
)
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'
,e.dogs AS 'Dogs'
,e.programmes AS 'Programmes'
,e.tt AS 'Touch tour'
,e.headset 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 AND c.primary_ind='Y' --Primary addresses only
JOIN T_EADDRESS d ON d.customer_no=a.customer_no AND d.primary_ind='Y' --Primary emails only
LEFT JOIN actions 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
WHERE a.activity_type=21 --'Access requirements' from TR_CUST_ACTIVITY_TYPE
ORDER BY f.perf_dt, a.customer_no ASC
答案 1 :(得分:0)
您可以在cte中使用您的查询并使用row_number来获得以下结果:
;With Cte as (
--your full query
), Cte2 as (
Select *, RowN = Row_Number() over(partition by Lname, Fname order by [Tour] desc)
, [HeadSetsMax] = max(headsets) over(Partition by Lname, Fname)
from Cte
)
Select * from Cte2 where RowN = 1
答案 2 :(得分:0)
我找到了一种方法来解决这个问题,使用MAX来对付每个CASE语句,这似乎有效:
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