[SQL] meerdere kolommen --> 1 kolom

Pagina: 1
Acties:
  • 220 views sinds 30-01-2008
  • Reageer

  • chicky
  • Registratie: Augustus 2001
  • Laatst online: 01-06-2025
Hoi,

ik wil een query maken die uit meerde kolommen de data ophaald en dat weergeeft in 1 kolom.

piet peter pascal
theo trudy tom
simon sandra
rob
henk hans harry harold

moet worden


hans
harold
harry
henk
pascal
peter
piet
rob
sandra
simon
theo
tom
trudy

kan iemand mij vertellen, hoe ik dat met SQL doe?

  • TukkerTweaker
  • Registratie: November 2001
  • Laatst online: 10:08
Dat kan ik wel vertellen, dat doe je met de concat functie.
select concat(voornaam, ' ', achternaam) as naam from persoon;

Verwijderd

Je hele database uitlezen, converteren met een geschikte programmeertaal, en alles in een nieuwe wél goed genormaliseerde database stoppen. Meerdere gegevens met een vergelijkbare betekenis in dezelde rij is geen goed plan, zéker niet als het in een enkel veld staat.

  • NetForce1
  • Registratie: November 2001
  • Laatst online: 11-02 16:00

NetForce1

(inspiratie == 0) -> true

Een simpele zoekopdracht in Google levert mij oa het volgende resultaat op: http://forge.mysql.com/snippets/view.php?id=4
Persoonlijk ben ik er echter niet zo van gecharmeerd. Kun je de data niet gelijk gescheiden opslaan met voor iedere naam een apart record oid? Ik weet niet hoe je datamodel eruit ziet, dus veel meer kan ik ook niet verzinnen.

De wereld ligt aan je voeten. Je moet alleen diep genoeg willen bukken...
"Wie geen fouten maakt maakt meestal niets!"


  • chicky
  • Registratie: Augustus 2001
  • Laatst online: 01-06-2025
Verwijderd schreef op donderdag 02 november 2006 @ 21:20:
Je hele database uitlezen, converteren met een geschikte programmeertaal, en alles in een nieuwe wél goed genormaliseerde database stoppen. Meerdere gegevens met een vergelijkbare betekenis in dezelde rij is geen goed plan, zéker niet als het in een enkel veld staat.
Dit is bijna het doel van de oefening 8)7
lijkt me makkelijk als ik eerst een goede querie kan schrijven om dat te doen.
Bovenstaand voorbeeld, is zeer sterk vereenvoudigd en allen bedoeld om het probleem duidelijker te maken.

de gegevens staan dan wel in dezelfde rij, maar niet in dezelfde kolom.
Wat ik wil is dat alles in alle rijen en kolommen in bijv in 1 kolom komen te staan

[ Voor 11% gewijzigd door chicky op 02-11-2006 21:31 ]


Verwijderd

chicky schreef op donderdag 02 november 2006 @ 21:25:

Dit is het doel van de oefening 8)7
lijkt me makkelijk als ik eerst een goede querie kan schrijven om dat te doen.
Bovenstaand voorbeeld, is zeer sterk vereenvoudigd en allen bedoeld om het probleem duidelijker te maken.
Alleen SQL is niet altijd dé oplossing. In dit geval volgens mij zéker niet. Waarom zou je niet een scriptje schrijven in een programmeertaal, dat eerst alle data uit de database leest, de boel opknipt, en dan weer terugschrijft in de database (of een andere database).

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Verwijderd schreef op donderdag 02 november 2006 @ 21:30:
Alleen SQL is niet altijd dé oplossing. In dit geval volgens mij zéker niet. Waarom zou je niet een scriptje schrijven in een programmeertaal, dat eerst alle data uit de database leest, de boel opknipt, en dan weer terugschrijft in de database (of een andere database).
SQL alleen kan waarschijnlijk wel, maar wordt erg gekunsteld idd. Je zou het kunnen oplossen met een combinatie van joins en unions waarbij je steeds een element verder gaat in de "lijst" van namen... vies en hoop gedoe.

Als je stored procedures kan gebruiken en die een "row" terug kunt laten geven, dan zou je een heel stuk verder moeten komen. Dan zal je iets als;
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE FUNCTION bla()
  RETURNS SETOF varchar
AS
BEGIN
FOR naamlijst IN SELECT naamVeld FROM naamTabel
  WHILE -- naamlijst has more spaces
     -- splits naamlijst in losse namen en return die los
     RETURN NEXT naam;
  END LOOP;
END LOOP;

RETURN;
END;


Maar tegen de tijd dat je dat goed en werkend in jouw specifieke procedurele sql-variant hebt verwerkt had je het waarschijnlijk ook in een normale programmeertaal kunnen doen ;)

  • chicky
  • Registratie: Augustus 2001
  • Laatst online: 01-06-2025
ik heb jullie raad ter harte genomen en in een stukje VB alles even in een kolom gezet.
Ik weet dat het in SQL niet zo makkelijk zou zijn, vandaar de vraag.

De oplossing is er nu wel, alleen niet via de weg die ik (stiekem) had gehoopt.

In ieder geval bedankt _/-\o_

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

chicky schreef op donderdag 02 november 2006 @ 22:25:
ik heb jullie raad ter harte genomen en in een stukje VB alles even in een kolom gezet.
Ik weet dat het in SQL niet zo makkelijk zou zijn, vandaar de vraag.
In PostgreSQL is het door het bestaan van de array's en de string_to_array functie triviaal. Ik wist dat het kon dus heb het voor de gein es gemaakt:

SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CREATE OR REPLACE FUNCTION bla()
  RETURNS SETOF text
AS
$BODY$
DECLARE 
  namer RECORD;
  i INT;
BEGIN
FOR namer IN SELECT string_to_array(namelist, ' ') as sepnames FROM names LOOP
  i := array_lower(namer.sepnames, 1);
  WHILE i <= array_upper(namer.sepnames, 1) LOOP
     RETURN NEXT namer.sepnames[i];
     i := i + 1;
  END LOOP;
END LOOP;

RETURN;
END;
$BODY$ LANGUAGE plpgsql;


En dan uiteraard:
testpg=# select * from names;
        namelist
------------------------
 piet peter pascal
 theo trudy tom
 simon sandra
 rob
 henk hans harry harold
(5 rows)

testpg=# select * from bla() order by bla;
  bla
--------
 hans
 harold
 harry
 henk
 pascal
 peter
 piet
 rob
 sandra
 simon
 theo
 tom
 trudy
(13 rows)


Hoe je het in je eigen db-omgeving op moet lossen durf ik niet te zeggen, de moeilijkheid van de functie hangt vrijwel volledig af van hoe lastig het opsplitsen in losse strings is van je naam-strings :)

Een alternatief is zoeken naar de eerste spatie vanaf 0 en dan een substring van 0 tot die spatie en vervolgens van die spatie tot de dan eerstvolgende, etc.
Pagina: 1