英文:
How to insert other column on pivot?
问题
我试图生成报告,因为在网站上花费的时间太长,所以我建立了查询,但我无法在透视表中插入其他列。
在示例数据中,每个培训都有不同的名称、分数和时间。
以下是您提供的SQL代码的翻译结果:
declare @idtraining as nvarchar (max)
declare @ScriptPivot as nvarchar (max)
declare @ScriptFinal as nvarchar (max)
-- 获取所有培训名称以用于透视
select @ScriptPivot = SELECT STUFF((SELECT ',' + '['+CAST(NM_TRAINING AS NVARCHAR(MAX))+']'
FROM TBL_TRAINING
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') ,1,1,'')
set @ScriptFinal = SELECT * FROM (
SELECT C.ID, C.USERNAME, A.NM_TRAINING, B.SCORE, B.TIME
FROM TBL_TRAINING A
JOIN TBL_DETAIL_TRAINING B ON B.ID_TRAINING = A.ID
JOIN TBL_USER C ON C.ID = B.ID_USER
-- 这里有很多连接
) AS SOURCETABLE PIVOT (MAX(SCORE) FOR NM_TRAINING IN ([T_1],[T_2],[T_3])) AS PIVOTTABLE
-- 打印 @ScriptFinal
到目前为止,我只知道如何添加一个列(培训或时间)。
我可以通过再次添加透视脚本来添加另一个时间列,但它会被添加到最后一列,而且我有100多个培训名称。
我尝试使用临时表然后使用透视,但我无法弄清楚如何将时间列插入列名列表中。
是否有办法获得相同的结果?
英文:
I am trying to make report, since it's take too long on website so I build the query, but I can't insert other column on pivot.
On example data each training have different names, score and time @user
create table TBL_USER (
ID int IDENTITY(1,1) PRIMARY KEY,
USERNAME varchar(50),
);
create table TBL_TRAINING(
ID int IDENTITY(1,1) PRIMARY KEY,
NM_TRAINING varchar(255),
);
create table TBL_DETAIL_TRAINING(
ID_DETAIL int IDENTITY(1,1) PRIMARY KEY,
ID_TRAINING int,
ID_USER varchar(50),
SCORE int,
TIME time,
);
INSERT INTO TBL_USER VALUES ('AA')
INSERT INTO TBL_USER VALUES ('BB')
INSERT INTO TBL_USER VALUES ('CC')
INSERT INTO TBL_TRAINING VALUES ('T_1')
INSERT INTO TBL_TRAINING VALUES ('T_2')
INSERT INTO TBL_TRAINING VALUES ('T_3')
INSERT INTO TBL_DETAIL_TRAINING VALUES ('1','1','80','00:50:00')
INSERT INTO TBL_DETAIL_TRAINING VALUES ('1','2','40','00:40:00')
INSERT INTO TBL_DETAIL_TRAINING VALUES ('1','3','60','00:10:00')
INSERT INTO TBL_DETAIL_TRAINING VALUES ('2','1','30','00:30:00')
INSERT INTO TBL_DETAIL_TRAINING VALUES ('2','2','40','00:50:00')
INSERT INTO TBL_DETAIL_TRAINING VALUES ('2','3','50','00:30:00')
INSERT INTO TBL_DETAIL_TRAINING VALUES ('3','1','100','00:50:00')
INSERT INTO TBL_DETAIL_TRAINING VALUES ('3','2','80','00:50:00')
INSERT INTO TBL_DETAIL_TRAINING VALUES ('3','3','70','00:30:00')
Sample Data
| ID_USER | Username | Name_Training | Score | Time |
|---------|----------|---------------|-------|----------|
| 1 | AA | T_1 | 80 | 00:50:00 |
| 2 | BB | T_1 | 40 | 00:40:00 |
| 3 | CC | T_1 | 60 | 00:10:00 |
| 1 | AA | T_2 | 30 | 00:30:00 |
| 2 | BB | T_2 | 40 | 00:50:00 |
| 3 | CC | T_2 | 50 | 00:30:00 |
| 1 | AA | T_3 | 100 | 00:50:00 |
| 2 | BB | T_3 | 80 | 00:50:00 |
| 3 | CC | T_3 | 70 | 00:30:00 |
Expected results
| ID_USER | Username | T_1 | Time_T_1 | T_2 | Time_T_2 | T_3 | Time_T_3 |
|---------|----------|-----|----------|-----|----------|-----|----------|
| 1 | AA | 80 | 00:50:00 | 30 | 00:30:00 | 100 | 00:50:00 |
| 2 | BB | 40 | 00:40:00 | 40 | 00:50:00 | 80 | 00:50:00 |
| 3 | CC | 60 | 00:10:00 | 50 | 00:30:00 | 70 | 00:30:00 |
declare @idtraining as nvarchar (max)
declare @ScriptPivot as nvarchar (max)
declare @ScriptFinal as nvarchar (max)
// GET ALL NAME TRAINING FOR PIVOT
select @ScriptPivot = SELECT STUFF((SELECT ',' + '['+CAST(NM_TRAINING AS NVARCHAR(MAX))+']'
FROM TBL_TRAINING
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') ,1,1,'')
set @ScriptFinal = SELECT * FROM (
SELECT C.ID, C.USERNAME, A.NM_TRAINING, B.SCORE, B.TIME
FROM TBL_TRAINING A
JOIN TBL_DETAIL_TRAINING B ON B.ID_TRAINING = A.ID
JOIN TBL_USER C ON C.ID = B.ID_USER
-- LOT JOIN HERE
) AS SOURCETABLE PIVOT (MAX(SCORE) FOR NM_TRAINING IN ([T_1],[T_2],[T_3])) AS PIVOTTABLE
--print @ScriptFinal
So far I only know add 1 column (training or time).
I can add another column time by adding pivot script again but it is added at the last column and I get more than 100 training names.
I tried using a temp table then using a pivot but I can't figure out how to insert the column times on the list column.
Is there a way to get the same result?
答案1
得分: 0
以下是您要翻译的内容:
*Not a complete answer, but you can work from this.
(不是完整的答案,但你可以从这里开始。)
I still don't understand the use of @idtraining
.
(我仍然不理解@idtraining
的用法。)
I added more training so you can see how dynamically added as columns.
(我添加了更多的训练,这样你可以看到它们如何动态添加为列。)
CREATE TABLE UserTraining (
ID_USER INTEGER,
Username VARCHAR(255),
Training VARCHAR(255),
Score INTEGER,
Time TIME
);
(创建名为UserTraining的表,包含ID_USER、Username、Training、Score和Time列。)
INSERT INTO UserTraining (ID_USER, Username, Training, Score, Time) VALUES
(1, 'AA', 'T_1', 80, '00:50:00'),
(2, 'BB', 'T_1', 40, '00:40:00'),
(3, 'CC', 'T_1', 60, '00:10:00'),
(1, 'AA', 'T_2', 30, '00:30:00'),
(2, 'BB', 'T_2', 40, '00:50:00'),
(3, 'CC', 'T_2', 50, '00:30:00'),
(3, 'CC', 'T_7', 50, '00:30:00'),
(1, 'AA', 'T_3', 100, '00:50:00'),
(2, 'BB', 'T_3', 80, '00:50:00'),
(2, 'BB', 'T_5', 80, '00:50:00'),
(3, 'CC', 'T_3', 70, '00:30:00');
(插入了一些示例数据到UserTraining表中。)
DECLARE @pivotColumns NVARCHAR(MAX),
@sql NVARCHAR(MAX)
(声明了两个变量@pivotColumns和@sql。)
Get the distinct training names for Score and Time
(获取得分和时间的不同训练名称。)
SELECT @pivotColumns = STUFF((SELECT DISTINCT ', ' + QUOTENAME(Training + '_Score') + ', ' + QUOTENAME(Training + '_Time')
FROM UserTraining
FOR XML PATH('')), 1, 2, '')
(将不同的训练名称连接成一个字符串并赋值给@pivotColumns变量。)
Build the dynamic pivot query
(构建动态的数据透视查询。)
SET @sql = '
WITH ScoreTable AS (
SELECT ID_USER, Username, Training + ''_Score'' AS Training, CAST(Score AS NVARCHAR) AS Value
FROM UserTraining
),
TimeTable AS (
SELECT ID_USER, Username, Training + ''_Time'' AS Training, CAST(Time AS NVARCHAR) AS Value
FROM UserTraining
)
SELECT ID_USER, Username, ' + @pivotColumns + '
FROM (
SELECT * FROM ScoreTable
UNION ALL
SELECT * FROM TimeTable
) AS SourceTable
PIVOT (
MAX(Value)
FOR Training IN (' + @pivotColumns + ')
) AS PivotTable
ORDER BY ID_USER'
(构建动态查询字符串并赋值给@sql变量。)
EXECUTE sp_executesql @sql
(执行动态查询。)
表格结果如下:
ID_USER | Username | T_1_Score | T_1_Time | T_2_Score | T_2_Time | T_3_Score | T_3_Time | T_5_Score | T_5_Time | T_7_Score | T_7_Time |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | AA | 80 | 00:50:00.0000000 | 30 | 00:30:00.0000000 | 100 | 00:50:00.0000000 | null | null | null | null |
2 | BB | 40 | 00:40:00.0000000 | 40 | 00:50:00.0000000 | 80 | 00:50:00.0000000 | 80 | 00:50:00.0000000 | null | null |
3 | CC | 60 | 00:10:00.0000000 | 50 | 00:30:00.0000000 | 70 | 00:30:00.0000000 | null | null | 50 | 00:30:00.0000000 |
(这是动态查询的结果,将数据透视为不同的列。) |
fiddle
(链接到示例数据的在线数据库演示。)
如果您需要任何进一步的翻译或解释,请告诉我。
英文:
*Not a complete answer, but you can work from this.
I still don't understand the use of @idtraining
.
I added more training so you can see how dynamically added as columns.
CREATE TABLE UserTraining (
ID_USER INTEGER,
Username VARCHAR(255),
Training VARCHAR(255),
Score INTEGER,
Time TIME
);
INSERT INTO UserTraining (ID_USER, Username, Training, Score, Time) VALUES
(1, 'AA', 'T_1', 80, '00:50:00'),
(2, 'BB', 'T_1', 40, '00:40:00'),
(3, 'CC', 'T_1', 60, '00:10:00'),
(1, 'AA', 'T_2', 30, '00:30:00'),
(2, 'BB', 'T_2', 40, '00:50:00'),
(3, 'CC', 'T_2', 50, '00:30:00'),
(3, 'CC', 'T_7', 50, '00:30:00'),
(1, 'AA', 'T_3', 100, '00:50:00'),
(2, 'BB', 'T_3', 80, '00:50:00'),
(2, 'BB', 'T_5', 80, '00:50:00'),
(3, 'CC', 'T_3', 70, '00:30:00');
DECLARE @pivotColumns NVARCHAR(MAX),
@sql NVARCHAR(MAX)
-- Get the distinct training names for Score and Time
SELECT @pivotColumns = STUFF((SELECT DISTINCT ', ' + QUOTENAME(Training + '_Score') + ', ' + QUOTENAME(Training + '_Time')
FROM UserTraining
FOR XML PATH('')), 1, 2, '')
-- Build the dynamic pivot query
SET @sql = '
WITH ScoreTable AS (
SELECT ID_USER, Username, Training + ''_Score'' AS Training, CAST(Score AS NVARCHAR) AS Value
FROM UserTraining
),
TimeTable AS (
SELECT ID_USER, Username, Training + ''_Time'' AS Training, CAST(Time AS NVARCHAR) AS Value
FROM UserTraining
)
SELECT ID_USER, Username, ' + @pivotColumns + '
FROM (
SELECT * FROM ScoreTable
UNION ALL
SELECT * FROM TimeTable
) AS SourceTable
PIVOT (
MAX(Value)
FOR Training IN (' + @pivotColumns + ')
) AS PivotTable
ORDER BY ID_USER'
EXECUTE sp_executesql @sql
ID_USER | Username | T_1_Score | T_1_Time | T_2_Score | T_2_Time | T_3_Score | T_3_Time | T_5_Score | T_5_Time | T_7_Score | T_7_Time |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | AA | 80 | 00:50:00.0000000 | 30 | 00:30:00.0000000 | 100 | 00:50:00.0000000 | null | null | null | null |
2 | BB | 40 | 00:40:00.0000000 | 40 | 00:50:00.0000000 | 80 | 00:50:00.0000000 | 80 | 00:50:00.0000000 | null | null |
3 | CC | 60 | 00:10:00.0000000 | 50 | 00:30:00.0000000 | 70 | 00:30:00.0000000 | null | null | 50 | 00:30:00.0000000 |
This is the resulting dynamic query:
WITH ScoreTable AS (
SELECT ID_USER, Username, Training + '_Score' AS Training, CAST(Score AS NVARCHAR) AS Value
FROM UserTraining
),
TimeTable AS (
SELECT ID_USER, Username, Training + '_Time' AS Training, CAST(Time AS NVARCHAR) AS Value
FROM UserTraining
)
SELECT ID_USER, Username, [T_1_Score], [T_1_Time], [T_2_Score], [T_2_Time], [T_3_Score], [T_3_Time], [T_5_Score], [T_5_Time], [T_7_Score], [T_7_Time]
FROM (
SELECT * FROM ScoreTable
UNION ALL
SELECT * FROM TimeTable
) AS SourceTable
PIVOT (
MAX(Value)
FOR Training IN ([T_1_Score], [T_1_Time], [T_2_Score], [T_2_Time], [T_3_Score], [T_3_Time], [T_5_Score], [T_5_Time], [T_7_Score], [T_7_Time])
) AS PivotTable
ORDER BY ID_USER
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论