Допустим, у меня есть две таблицы, table1
и table2
, которые я хочу развернуть с помощью cte view uvw_TestView
.
table1
id1 | name | locationCode
----|------|-----------------
1 | a | 3
2 | b | 1
3 | c | 2
table2
id2 | id1 | StudyName | dateStudy
----|-----|-----------|------
1 | 1 | Math | 2015-05-23
2 | 1 | Chemistry | 2015-06-20
3 | 2 | Math | 2016-09-02
4 | 3 | Physics | 2016-12-26
5 | 2 | Chemistry | 2017-01-05
6 | 2 | Math | 2017-06-06
7 | 3 | Chemistry | 2018-02-22
Представление здесь - просто вздор, где учатся люди из table1
.
ожидаемый результат будет примерно таким, если дата отфильтрована из 2015-05-01
в2017-01-01
id1 | name | Math | Chemistry | Physics
1 | a | 2015-05-23 | 2015-06-20 | ---
2 | b | 2016-09-02 | --- | ---
3 | c | --- | --- | 2016-12-26
Мне очень жаль, что я не могу показать реальный запрос здесь, но я пытаюсь сделать его похожим на него.
Я пытался использоватьэтот запрос без фильтра даты
DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX), @dtDate1 DATETIME, @dtDate2 DATETIME;
SET @dtDate1 = '2015-05-01'
SET @dtDate2 = '2017-01-01'
SET @columns = N'';
SELECT @columns += N', ' + QUOTENAME(StudyName)
FROM (SELECT DISTINCT t2.StudyName FROM dbo.table2 AS t2) AS x;
SET @sql = N'
WITH cte AS
(
SELECT * FROM dbo.uvw_TestView WHERE idView = '001'
UNION ALL
SELECT a.* FROM dbo.uvw_TestView a INNER JOIN cte b ON a.ParentID = b.idView
SELECT * FROM
(SELECT DISTINCT * FROM cte) ct
INNER JOIN (
SELECT p.*, ' + STUFF(@columns, 1, 2, '') + '
FROM
(
SELECT DISTINCT
tb1.id1,
tb1.name,
tb2.dateStudy,
tb2.StudyName
FROM dbo.table1 AS tb1
INNER JOIN dbo.table2 tb2 tb2
ON tb1.id1 = tb2.id1
) AS j
PIVOT
(
MIN(dateStudy) FOR StudyName IN ('
+ STUFF(REPLACE(@columns, ', [', ',['), 1, 1, '')
+ ')
) AS p) tbl ON tbl.id1 = ct.id1';
PRINT @sql;
EXEC sp_executesql @sql;
но получите ошибку The column 'Math' was specified multiple times for 'tbl'.
Я также попытался с фильтром даты
SELECT @columns += N', ' + QUOTENAME(StudyName)
FROM (SELECT DISTINCT t2.StudyName FROM dbo.table2 AS t2) AS x;
SET @sql = N'
WITH cte AS
(
SELECT * FROM dbo.uvw_TestView WHERE idView = '001'
UNION ALL
SELECT a.* FROM dbo.uvw_TestView a INNER JOIN cte b ON a.ParentID = b.idView
SELECT * FROM
(SELECT DISTINCT * FROM cte) ct
INNER JOIN (
SELECT p.*, ' + STUFF(@columns, 1, 2, '') + '
FROM
(
SELECT DISTINCT
tb1.id1,
tb1.name,
tb2.dateStudy,
tb2.StudyName
FROM dbo.table1 AS tb1
INNER JOIN dbo.table2 tb2 tb2
ON tb1.id1 = tb2.id1
) AS j
PIVOT
(
MIN(dateStudy) FOR StudyName IN ('
+ STUFF(REPLACE(@columns, ', [', ',['), 1, 1, '')
+ ')
) AS p) tbl ON tbl.id1 = ct.id1 where tbl.dateStudy BETWEEN ''' + @dtDate1 +''' AND ''' + @dtDate2;
и получил ошибку String or binary data would be truncated.
Итак, как мне исправить эту ошибку, чтобы получить результат?