Reputation: 333
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?
Upvotes: 0
Views: 1483
Reputation: 24773
i see you have a PRINT @sql;
statement. But did you take a look at the query ?
the error The column 'Math' was specified multiple times for 'tbl'.
is due to this line
SELECT p.*, ' + STUFF(@columns, 1, 2, '') + '
your columns
would contains the list of columns like [Chemistry], [Math]
and p.*
actually contains all column from the PIVOT
result. So those pivot columns are duplicates
You can just do a SELECT *
instead and it should be sufficient.
Upvotes: 1