So let's say that I have two tables, table1 and table2, that I want to pivot with a 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
The view here is just a loation where people from table1 study.
the expected result is something like this if the date filtered from 2015-05-01 to 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
I'm so sorry that I can't show the real query here, but I try to make it similar with it.
I've tried to used this query without the date filter
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;
But get the error The column 'Math' was specified multiple times for 'tbl'.
I also tried with the date filter
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;
and get the error String or binary data would be truncated.
So, how I resolve this error to get the result?
SELECT *. If you doSELECT *with a join, then you would see your current error message if two (or more) tables happened to have one or more columns with the same name. To fix this, list out explicitly the columns you want, and alias columns having the same name.