Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pivoting a Table with Text and no Aggregation

I've been looking through StackOverflow questions and haven't really found one for this issue.

I have a table that's arranged basically like:

Table.LineID
Table.QuestionGroup
Table.Question
Table.Answer

And I'd like to "pivot" the table, but the questions and answers don't have anything to aggregate. They're all just text fields for example, one might read:

Table.LineID = 00001
Table.QuestionGroup = Color
Table.Question = Outside Color
Table.Answer = Dark Green

Table.LineID = 00001
Table.QuestionGroup = Size
Table.Question = Height
Table.Answer = 180 3/4

I'm trying to pivot the table so that I can get the associated ID of line and make that the spreading function the Questions So it would look like

LineID | Question 1 | Question 2 | Etc...

| Answer 1 | Answer 2 | Etc...

I've looked at this https://stackoverflow.com/a/7744347/839330 except this seems to be more in reference to some VB code (maybe I'm wrong?). Does anyone have an idea on how I should approach this?

like image 536
Sevdarkseed Avatar asked Jan 15 '23 11:01

Sevdarkseed


1 Answers

Just because you have text data in your table does not mean that you cannot use an aggregate function on it.

You did not specify what RDBMS you are using but this type of data transformation is a pivot. This converts row data into columns. Some databases has a pivot function but if you are using one without that function, then you will need to use an aggregate function with a CASE expression:

select lineid,
  max(case when question ='Height' then answer else '' end) Height,
  max(case when question ='Outside Color' then answer else '' end) [Outside Color]
from yourtable 
group by lineid

See SQL Fiddle with Demo

If you have a database that has the pivot function (SQL Server 2005+/Oracle 11g+), then your code will be similar to this:

select *
from 
(
  select lineid,
    Question,
    Answer
  from yourtable
) src
pivot
(
  max(answer)
  for question in ([Height], [Outside Color])
) piv;

See SQL Fiddle with Demo

Now if you are using SQL Server 2005+ and you have an unknown number of questions that you want to turn into columns, then you can use dynamic sql similar to this:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(Question) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT lineid,' + @cols + ' from 
             (
                select lineid,
                  Question,
                  Answer
                from yourtable
            ) x
            pivot 
            (
                max(Answer)
                for Question in (' + @cols + ')
            ) p '

execute(@query)

See SQL Fiddle with demo

Based on your sample data the result is:

| LINEID |  HEIGHT | OUTSIDE COLOR |
------------------------------------
|      1 | 180 3/4 |    Dark Green |
like image 171
Taryn Avatar answered Jan 17 '23 04:01

Taryn