在未知数量的列上执行数据透视时转换失败

时间:2018-02-06 18:11:40

标签: sql-server

我试图动态列出代表在事件中预订的每个会话,但会话数量因事件而异。因此,我一直在寻找执行此操作的解决方案such as thisPIVOT in sql 2005)。我想避免手动使用LEFT JOIN!

使用上面示例中的代码(见下文),我收到“转换失败”错误。我在这做错了什么?

感谢您的任何指示! (对于错误格式化,我的第一个更复杂的查询道歉!)

创建表/数据的代码:

CREATE TABLE delegate(
   DELEGATE_REF      INTEGER  NOT NULL PRIMARY KEY 
  ,code              INTEGER  NOT NULL
  ,name              VARCHAR(10) NOT NULL
  ,MEMBER_REF        INTEGER  NOT NULL
  ,TOTAL_AMOUNT      INTEGER  NOT NULL
  ,DELEGATE_SESS_REF INTEGER  NOT NULL
  ,EVENT_REF         INTEGER  NOT NULL
);
INSERT INTO delegate(DELEGATE_REF,code,name,MEMBER_REF,TOTAL_AMOUNT,DELEGATE_SESS_REF,EVENT_REF) VALUES (26174,51,'Delegate A',1077419,280,58136,378);
INSERT INTO delegate(DELEGATE_REF,code,name,MEMBER_REF,TOTAL_AMOUNT,DELEGATE_SESS_REF,EVENT_REF) VALUES (26183,52,'Delegate B',1110544,302,58157,378);
INSERT INTO delegate(DELEGATE_REF,code,name,MEMBER_REF,TOTAL_AMOUNT,DELEGATE_SESS_REF,EVENT_REF) VALUES (26206,53,'Delegate C',1084626,169,58209,378);
INSERT INTO delegate(DELEGATE_REF,code,name,MEMBER_REF,TOTAL_AMOUNT,DELEGATE_SESS_REF,EVENT_REF) VALUES (26210,54,'Delegate D',1092456,257,58218,378);
INSERT INTO delegate(DELEGATE_REF,code,name,MEMBER_REF,TOTAL_AMOUNT,DELEGATE_SESS_REF,EVENT_REF) VALUES (26212,55,'Delegate E',1055867,221,58223,378);
INSERT INTO delegate(DELEGATE_REF,code,name,MEMBER_REF,TOTAL_AMOUNT,DELEGATE_SESS_REF,EVENT_REF) VALUES (26220,56,'Delegate F',1109833,169,58240,378);
INSERT INTO delegate(DELEGATE_REF,code,name,MEMBER_REF,TOTAL_AMOUNT,DELEGATE_SESS_REF,EVENT_REF) VALUES (26229,57,'Delegate G',266050,0,58258,378);
INSERT INTO delegate(DELEGATE_REF,code,name,MEMBER_REF,TOTAL_AMOUNT,DELEGATE_SESS_REF,EVENT_REF) VALUES (26230,58,'Delegate H',1110868,0,58260,378);
INSERT INTO delegate(DELEGATE_REF,code,name,MEMBER_REF,TOTAL_AMOUNT,DELEGATE_SESS_REF,EVENT_REF) VALUES (26231,59,'Delegate I',1110890,0,58262,378);
INSERT INTO delegate(DELEGATE_REF,code,name,MEMBER_REF,TOTAL_AMOUNT,DELEGATE_SESS_REF,EVENT_REF) VALUES (26232,60,'Delegate J',1110891,0,58264,378);

CREATE TABLE event(
   code      VARCHAR(6) NOT NULL
  ,event_ref INTEGER  NOT NULL PRIMARY KEY 
  ,name      VARCHAR(12) NOT NULL
);
INSERT INTO event(code,event_ref,name) VALUES ('AC2017',378,'MyConference');


CREATE TABLE delegate_session(
   DELEGATE_REF      INTEGER  NOT NULL
  ,DELEGATE_SESS_REF INTEGER  NOT NULL PRIMARY KEY 
  ,SESSION_REF       INTEGER  NOT NULL
  ,NO_DELEGATES      INTEGER  NOT NULL
);
INSERT INTO delegate_session(DELEGATE_REF,DELEGATE_SESS_REF,SESSION_REF,NO_DELEGATES) VALUES (26183,58157,460,1);
INSERT INTO delegate_session(DELEGATE_REF,DELEGATE_SESS_REF,SESSION_REF,NO_DELEGATES) VALUES (26206,58209,460,1);
INSERT INTO delegate_session(DELEGATE_REF,DELEGATE_SESS_REF,SESSION_REF,NO_DELEGATES) VALUES (26212,58223,460,1);
INSERT INTO delegate_session(DELEGATE_REF,DELEGATE_SESS_REF,SESSION_REF,NO_DELEGATES) VALUES (26220,58240,460,1);
INSERT INTO delegate_session(DELEGATE_REF,DELEGATE_SESS_REF,SESSION_REF,NO_DELEGATES) VALUES (26229,58258,460,1);
INSERT INTO delegate_session(DELEGATE_REF,DELEGATE_SESS_REF,SESSION_REF,NO_DELEGATES) VALUES (26230,58260,460,1);
INSERT INTO delegate_session(DELEGATE_REF,DELEGATE_SESS_REF,SESSION_REF,NO_DELEGATES) VALUES (26231,58262,460,1);
INSERT INTO delegate_session(DELEGATE_REF,DELEGATE_SESS_REF,SESSION_REF,NO_DELEGATES) VALUES (26232,58264,460,1);
INSERT INTO delegate_session(DELEGATE_REF,DELEGATE_SESS_REF,SESSION_REF,NO_DELEGATES) VALUES (26174,58136,460,1);
INSERT INTO delegate_session(DELEGATE_REF,DELEGATE_SESS_REF,SESSION_REF,NO_DELEGATES) VALUES (26210,58218,460,1);
INSERT INTO delegate_session(DELEGATE_REF,DELEGATE_SESS_REF,SESSION_REF,NO_DELEGATES) VALUES (26230,58300,461,1);
INSERT INTO delegate_session(DELEGATE_REF,DELEGATE_SESS_REF,SESSION_REF,NO_DELEGATES) VALUES (26231,58301,461,1);
INSERT INTO delegate_session(DELEGATE_REF,DELEGATE_SESS_REF,SESSION_REF,NO_DELEGATES) VALUES (26232,58302,461,1);
INSERT INTO delegate_session(DELEGATE_REF,DELEGATE_SESS_REF,SESSION_REF,NO_DELEGATES) VALUES (26174,58303,461,1);
INSERT INTO delegate_session(DELEGATE_REF,DELEGATE_SESS_REF,SESSION_REF,NO_DELEGATES) VALUES (26210,58304,461,1);

CREATE TABLE session(
   SESSION_REF INTEGER  NOT NULL PRIMARY KEY 
  ,NAME        VARCHAR(16) NOT NULL
);
INSERT INTO session(SESSION_REF,NAME) VALUES (460,'Delegate booking');
INSERT INTO session(SESSION_REF,NAME) VALUES (461,'Dinner booking');

这是我为了尝试获取动态输出而修改的代码:

DECLARE @sql AS varchar(max)
DECLARE @pivot_list AS varchar(max) -- Leave NULL for COALESCE technique
DECLARE @select_list AS varchar(max) -- Leave NULL for COALESCE technique

SELECT @pivot_list = COALESCE(@pivot_list + ', ', '') + PIVOT_CODE
        , @select_list = COALESCE(@select_list + ', ', '') + 'ISNULL(' + PIVOT_CODE + ', 0) AS ' + PIVOT_CODE
FROM (
    SELECT DISTINCT s.SESSION_REF AS PIVOT_CODE
FROM DELEGATE as d
INNER JOIN DELEGATE_SESSION as ds on d.DELEGATE_REF=ds.DELEGATE_REF
INNER JOIN SESSION as s on ds.SESSION_REF=s.SESSION_REF
where ds.NO_DELEGATES=1 and d.EVENT_REF=378
) AS PIVOT_CODES

SET @sql = '
;WITH p AS (

select d.DELEGATE_REF, s.SESSION_REF AS PIVOT_CODE, d.name, ds.NO_DELEGATES
FROM DELEGATE as d
INNER JOIN DELEGATE_SESSION as ds on d.DELEGATE_REF=ds.DELEGATE_REF
INNER JOIN SESSION as s on ds.SESSION_REF=s.SESSION_REF
where ds.NO_DELEGATES=1 and s.EVENT_REF=378
)
SELECT DELEGATE_REF, NO_DELEGATES, ' + @select_list + '
FROM p
PIVOT (
    SUM(NO_DELEGATES)
    FOR PIVOT_CODE IN (
        ' + @pivot_list + '
    )
) AS pvt
'
EXEC (@sql)

这是我目前用于手动拉入具有子查询的会话的查询(以显示我想要实现的目标):

select e.NAME, d.code, d.name, d.MEMBER_REF, d.TOTAL_AMOUNT, x1.t1 as 'Session 1', x2.t1 as 'Session 2'

from DELEGATE as d
INNER JOIN EVENT as e on d.EVENT_REF=e.EVENT_REF

left join (select d.DELEGATE_REF, s.name as 't1'
FROM DELEGATE as d
INNER JOIN DELEGATE_SESSION as ds on d.DELEGATE_REF=ds.DELEGATE_REF
INNER JOIN SESSION as s on ds.SESSION_REF=s.SESSION_REF
where s.SESSION_REF=460
) as x1 on d.DELEGATE_REF=x1.delegate_ref

left join (select d.DELEGATE_REF, s.name as 't1'
FROM DELEGATE as d
INNER JOIN DELEGATE_SESSION as ds on d.DELEGATE_REF=ds.DELEGATE_REF
INNER JOIN SESSION as s on ds.SESSION_REF=s.SESSION_REF
where s.SESSION_REF=461
) as x2 on d.DELEGATE_REF=x2.delegate_ref

where d.code > 50 and d.code < 61 and e.code like 'ac2017'

group by e.NAME, d.code, d.name, d.MEMBER_REF, d.TOTAL_AMOUNT, x1.t1, x2.t1

0 个答案:

没有答案