Lekérdezés - sorokból oszlop

Sziasztok!

A következő a probléma, amire szeretnék megoldást találni: van 1 db tábla amiben a következő séma szerint vannak az adatok
nev azonosito gyujto adat
--------------------------------------
aaaa 1234 1 344
aaaa 1234 2 543
aaaa 1234 3 876
stb.
Az lenne a lényeg, hogy a lekérdezés eredménye a következő legyen:
nev azonosito 1 2 3
-----------------------------------------
aaaaa 1234 344 543 876

Milyen ötletetek van?

Hozzászólások

Könnyen futtatható demó; majd átírod, ahogy neked kell:


#!/bin/bash

(read nev1 azonosito1 gyujto adat
while [ ! -z "$nev1" ] ; do
  echo -n "$nev1 $azonosito1 $adat"
  while read nev2 azonosito2 gyujto adat   &&
        [ "$nev1" = "$nev2" -a "$azonosito1" = "$azonosito2" ] ; do
    echo -n " $adat"
  done
  echo
  nev1=$nev2
  azonosito1=$azonosito2
done)<<END | column -t
aaaa 1234 1 344
aaaa 1234 2 543
aaaa 1234 3 876
b 2 1 21
b 2 2 22
b 2 3 23
b 2 4 24
b 2 5 25
END

output:


aaaa  1234  344  543  876
b     2     21   22   23   24  25

Hogy elegánsan lehet-e, arról nem vagyok meggyőződve (rafinált sql-eket láttam már e tájon hasonló topicokban, de mindegyik erőszaktevés volt), viszont nem elegánsan elég gyorsan lehet:
a) vagy lekérdezni PowerShellben, és az ID alapján faragni a kimenetet,
b) vagy kinyomni CSV-be, aztán visszaolvasni PowerShellben, és átfaragni a kimenetet.

PS ismeret hiánya esetén persze b)-re alternatíva lehet egy natív wines awk, amihez lófütty lábnyomú, nem kell ráarőszakolni se cygwint, se libhalmazt a gépre.

Teljesen valid, csak azért írok mellé egy alternatívát, mert - db lekérdezés eredményéről lévén szó - a szűrendő rekordmennyiség akármekkora lehet, kár volna feleslegesen tárolni bármit.
Persze előfeltétel, hogy a resultset az első 2 mező szerint legyen rendezve.


{
key = $1 " " $2
if ( key != oldkey) {
if ( NR > 1) {
print str
}
str = key " " $4
oldkey = key
} else {
str = str " " $4
}
}

END {
print str
}

Sajnos a pivot feltételezi 1-2 adat ismeretét, és literális sql-be írását.

Amiből - fokozva a feltételezések szélsőségességét - következik egy triviális, self-joinos megoldás is:


select a.name, a.id, a.value, b.value, c.value
from
tab a
left outer join tab b on b.id=a.id and b.counter = a.counter+1
left outer join tab c on c.id=b.id and c.counter = b.counter+1
where a.counter = 1"

A feltételezés az, hogy a gyujto (itt: counter) adott id-ra hézagmentesen, 1--től indulva, egyes lépésközzel nő.
A szelektált mezők és left joinok száma hardkódolt (pivot-analógia) - editor és maxsqltextlength kérdése.
És persze pont olyan ronda az egész, mint amilyenre utaltam a topic elején.

esetleg valami ilyes?


select

    nev
    ,azonosito
    ,max(case when gyujto=1 then adat end) as gy1
    ,max(case when gyujto=2 then adat end) as gy2
    ,max(case when gyujto=3 then adat end) as gy3
    ,max(case when gyujto=4 then adat end) as gy4
    ,max(case when gyujto=5 then adat end) as gy5
    ....
    ,max(case when gyujto=1000 then adat end) as gy1000

from

    table

group by nev,azonosito

Persze lehetne generáltatni ezt is SQL-el, a max/distinct (izlés szerint) gyüjtő alapján.

Ez lett a megoldás. Köszönöm! Mivel óra állás adatok összegyűjtéséről van szó, így a "max" lett a tuti, hiszen optimális esetben a mérőóra számlálója nem csökken, csak nő. Mivel az utolsó állásra van szükség, ami ha nem növekedett, a query visszaadja az utolsó legnagyobb értéket.

Elvi hiba azt feltételezni, hogy az érték csak növekedhet, ugyanis a mérő x érték után át fog fordulni, és máris nem a maximális érték az utolsó, hanem a leolvasási idő szerinti legfrissebb. Ha ilyen időadatot nem tároltok még, akkor remélem időben szólok, hogy kéne...

+1. Meg azt se felejtsük már el, hogy attól, hogy elektronikus számlálóval rendelkező műszerről van szó, attól még van a számábrázolásnak maximális felső értéke. (Egyébként meg egy hagyományos számlálóművel mérő is digitális, már ami a kijelzést illeti...)

Feltetelezem MsSql-ben is van tarolteljaras, abban siman megoldhato.