How to Convert Columns to Rows in Sql Server 2008 R2?

8.3k views Asked by At

I have a table like this

enter image description here

and the result should be like this

enter image description here

i am little bit confused about Pivot and unpivot and cross apply. can anyone help me from this.

2

There are 2 answers

0
Andomar On BEST ANSWER

You are pivoting on two columns (department, [check/uncheck]). As far as I know, that means you cannot use SQL Server's pivot syntax.

One way is to "unpivot" (aka "normalize") checked in a subquery. You can then "pivot" (aka "denormalize") the tools column in the outer query:

select  department
,       [Check/Uncheck]
,       sum(case when tools = 'engine' then nr else 0 end) as engine
,       sum(case when tools = 'oils' then nr else 0 end) as oils
,       sum(case when tools = 'grease' then nr else 0 end) as grease
,       sum(case when tools = 'sounds' then nr else 0 end) as sounds
,       sum(case when tools = 'wapers' then nr else 0 end) as wapers
from    (
        select  department
        ,       tools
        ,       'Checked' as [Check/Uncheck]
        ,       checked as nr
        from    dbo.YourTable
        union all
        select  department
        ,       tools
        ,       'Unchecked'
        ,       unchecked
        from    dbo.YourTable
        ) as SubQueryAlias
group by
        Department
,       [Check/Uncheck]
order by
        Department
,       [Check/Uncheck]

Live example at SQL Fiddle.

0
Taryn On

You can use the PIVOT function to get the result, but first you will want to unpivot the unchecked and checked columns. Since you are using SQL Server 2008r2, you can use CROSS APPLY to UNPIVOT the columns into multiple rows.

The basic syntax for CROSS APPLY will be:

select department, tools,
  [check/uncheck],
  value
from yourtable
cross apply
(
  values
    ('checked', checked),
    ('unchecked', unchecked)
) c([check/uncheck], value);

See Demo, this gets your data into the format:

| DEPARTMENT |  TOOLS | CHECK/UNCHECK | VALUE |
|------------|--------|---------------|-------|
|   Maintain | engine |       checked |     0 |
|   Maintain | engine |     unchecked |     0 |
|   Maintain |   oils |       checked |     0 |
|   Maintain |   oils |     unchecked |     2 |

Once the data has been converted into this format, then you can use the PIVOT function to turn your tools into columns:

select department,
  [check/uncheck],
  engine, oils, grease, sounds, wapers
from
(
  select department, tools,
    [check/uncheck],
    value
  from yourtable
  cross apply
  (
    values
      ('checked', checked),
      ('unchecked', unchecked)
  ) c([check/uncheck], value)
) d
pivot
(
  sum(value)
  for tools in (engine, oils, grease, sounds, wapers)
) piv
order by department;

See SQL Fiddle with Demo. This will give a result of:

| DEPARTMENT | CHECK/UNCHECK | ENGINE | OILS | GREASE | SOUNDS | WAPERS |
|------------|---------------|--------|------|--------|--------|--------|
|   Maintain |       checked |      0 |    0 |      5 |      0 |      0 |
|   Maintain |     unchecked |      0 |    2 |      1 |      0 |      0 |
| Operations |       checked |      1 |    2 |      1 |      5 |      0 |
| Operations |     unchecked |      0 |    1 |      2 |      1 |      2 |