1

I've looking everywhere and have not finding anything useful.

I have a table the captures assistance for employees.

The table that looks like this:

ID   | DATE     | ATTENDANCE
________________
2524 | 20121001 | ASISTANCE
2525 | 20121001 | ABSCENCE
2526 | 20121001 | ASISTANCE
2527 | 20121001 | ASISTANCE
2524 | 20121002 | ASISTANCE
2525 | 20121002 | ABSCENCE
2526 | 20121002 | ASISTANCE
2527 | 20121002 | ASISTANCE
2524 | 20121003 | ASISTANCE
2525 | 20121003 | DAY OFF
2526 | 20121003 | DAY OFF
2527 | 20121003 | ASISTANCE

And I want a query that returns a table that will look like this:

ID   | 20121001  | 20121002  | 20121003
________________
2524 | ASISTANCE | ASISTANCE | ASISTANCE
2525 | ABSCENCE  | ABSCENCE  | DAY OFF
2526 | ASISTANCE | ASISTANCE | ASISTANCE
2527 | ASISTANCE | ASISTANCE | DAY OFF

I tried individual querys and joining them, but since they are to many dates it takes too much to do so.

How can I do it that is efficient and can be stored into a view or function??

Taryn
  • 242,637
  • 56
  • 362
  • 405
zzzamo
  • 27
  • 1
  • 3
    Your *caps lock* key appears to be malfunctioning. – nneonneo Oct 17 '12 at 04:07
  • And while you're at it, please learn how to spell the word "assistance". –  Oct 17 '12 at 04:52
  • What database are you using? If you are using Microsoft SQL Server, you would be able to use [PIVOT](http://msdn.microsoft.com/en-us/library/ms177410%28v=sql.105%29.aspx). This is not standard SQL, and other databases may nor may not support something similar. – Sualeh Fatehi Oct 17 '12 at 04:05

2 Answers2

1

It would be easier to get the data and process it in a server-side language like PHP. It would then be a trivial matter to build the array:

$entry[$id][$date] = $status;

Then:

echo "ID";
foreach(array_keys(array_values($entry)[0]) as $date) {
    // requires some temporary variables in PHP before 5.4
    echo "\t".$date;
}
foreach($entry as $id=>$days) {
    echo "\n".$id;
    foreach($days as $day) echo "\t".$day;
}

You now have a tab-separated table.

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
0

Actually, this can be done with the PIVOT function. There are two ways to use PIVOT, either static or dynamic.

Static Pivot, you will hard-code the values to turn into columns:

create table tablea
(
    id int,
    dt datetime,
    attendance varchar(20)
);

insert into tablea values
(2524 , '20121001' , 'ASISTANCE'),
(2525 , '20121001' , 'ABSCENCE'),
(2526 , '20121001' , 'ASISTANCE'),
(2527 , '20121001' , 'ASISTANCE'),
(2524 , '20121002' , 'ASISTANCE'),
(2525 , '20121002' , 'ABSCENCE'),
(2526 , '20121002' , 'ASISTANCE'),
(2527 , '20121002' , 'ASISTANCE'),
(2524 , '20121003' , 'ASISTANCE'),
(2525 , '20121003' , 'DAY OFF'),
(2526 , '20121003' , 'DAY OFF'),
(2527 , '20121003' , 'ASISTANCE');

select *
from
(
    select id, dt, attendance
    from tablea
) x
pivot
(
    max(attendance)
    for dt in ([2012-10-01], [2012-10-02], [2012-10-03])
) p;

A dynamic PIVOT will get the list of values at run-time and will be more flexible if the list is changing:

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(convert(char(10), dt, 120)) 
                    from tablea
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT id, ' + @cols + ' from 
             (
                select id, dt, attendance
                from tablea
            ) x
            pivot 
            (
                max(attendance)
                for dt in (' + @cols + ')
            ) p '

execute(@query)

Both will give the same result:

id   | 2012-10-01 | 2012-10-02 | 2012-10-03
-------------------------------------------
2524 | ASISTANCE  | ASISTANCE  | ASISTANCE
2525 | ABSCENCE   | ABSCENCE   | DAY OFF
2526 | ASISTANCE  | ASISTANCE  | DAY OFF
2527 | ASISTANCE  | ASISTANCE  | ASISTANCE
Taryn
  • 242,637
  • 56
  • 362
  • 405