0

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?

2
  • 1
    You print the sql you're executing but you didn't include it in your post? Would be helpful to see Commented Sep 21, 2018 at 4:00
  • I can't see the exact problem, but it almost certainly would be caused by your use of SELECT *. If you do SELECT * 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. Commented Sep 21, 2018 at 4:00

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Oh, so that's why my columns duplicate, thank you, it's work

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.