[SQL] 2 kolommen uit resultset samenvoegen

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

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Ik heb 4 tabellen:

code:
1
2
3
4
5
6
nodes    users  articles  comments
-------  -----  --------  --------
nid      uid    nid       nid
type     name   body      body
title
created


Nu wil ik een overzicht maken van alle articles en comments. Elke content item (dus: elke article en comment) heeft een verwijzing in de nodes tabel:

SQL:
1
2
3
4
5
6
7
SELECT n. * , a.body, c.body, u.name
FROM nodes n
  LEFT JOIN articles a ON a.nid = n.nid
  LEFT JOIN comments c ON c.nid = n.nid
  LEFT JOIN users u ON u.uid = n.uid
WHERE n.type IN ('article', 'comment')
LIMIT 0 , 30


Deze query doet het in principe wel, alleen retourneert hij 2 "body" kolommen:

code:
1
2
3
4
nid type    title         created    uid body   body      name
1   article nieuw bericht 1167240437 2   blaat! NULL      admin
2   article morgen ziek   1167242131 5   blaat! NULL      erik
4   comment vrienden      1170100203 5   NULL   Jij en ik erik


Met andere woorden: er wordt een body kolom aangemaakt voor de types article en comment. Hoe kan ik ervoor zorgen dat er in de resultset slechts 1 body kolom staat, met andere woorden:

code:
1
2
3
4
nid type    title         created    uid body      name
1   article nieuw bericht 1167240437 2   blaat!    admin
2   article morgen ziek   1167242131 5   blaat!    erik
4   comment vrienden      1170100203 5   Jij en ik erik


Ik probeerde onderstaande al, maar dit leidde tot hetzelfde resultaat:
  • WHERE type = 'article' OR type = 'comment' IPV IN ('article', 'comment')
  • SELECT n. * , a.body AS body, c.body AS body
Wie weet de oplossing?

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


  • justmental
  • Registratie: April 2000
  • Niet online

justmental

my heart, the beat

Het makkelijkste is waarshijnlijk met een met een ifnull achtige functie (is afhankelijk van je dbms).
Dus ifnull(a.body, c.body) body.

Anders kan het met een union all.

Who is John Galt?


  • xos
  • Registratie: Januari 2002
  • Laatst online: 25-11 17:08

xos

Je kan in dit geval a.body en c.body misschien concateneren naar 1 kolom?

Of je gebruikt de union operator en voegt een query voor de acticles en de query voor de comments samen.

pff, wat justmental dus 4 minuten geleden al zegt...

[ Voor 13% gewijzigd door xos op 11-02-2007 21:32 ]


  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
xos schreef op zondag 11 februari 2007 @ 21:31:
Je kan in dit geval a.body en c.body misschien concateneren naar 1 kolom?
SQL:
1
2
3
4
5
6
7
SELECT n .  * , CONCAT(a.body, c.body) AS body, u.name
FROM nodes n
LEFT  JOIN articles a ON a.nid = n.nid
LEFT  JOIN comments c ON c.nid = n.nid
LEFT  JOIN users u ON u.uid = n.uid
WHERE n.type
IN (  'article',  'comment' )

Levert een resultset op waarbij in elke rij de "body" kolom NULL is...
Of je gebruikt de union operator en voegt een query voor de acticles en de query voor de comments samen.
Ik was niet bekent met de UNION operator. Maar na de betreffende MySQL documentatie bekeken te hebben, vraag ik me af of dit geen overkill is voor dit probleem. Er moet toch een eenvoudigere manier zijn?
pff, wat justmental dus 4 minuten geleden al zegt...
Jij ook bedankt, justmental :)

[ Voor 8% gewijzigd door Reveller op 11-02-2007 21:47 ]

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Verwijderd

SQL:
1
ISNULL(a.body, c.body) as body

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Verwijderd schreef op zondag 11 februari 2007 @ 21:46:
SQL:
1
ISNULL(a.body, c.body) as body
SQL:
1
2
3
4
5
6
SELECT n. * , ISNULL(a.body, c.body) AS body, u.name
FROM nodes n
  LEFT JOIN articles a ON a.nid = n.nid
  LEFT JOIN comments c ON c.nid = n.nid
  LEFT JOIN users u ON u.uid = n.uid
WHERE n.type IN ('article', 'comment')
MySQL said:
#1064 - You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near ' c.body ) AS body, u.name
FROM nodes n
LEFT JOIN articles a ON
:?

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


  • xos
  • Registratie: Januari 2002
  • Laatst online: 25-11 17:08

xos

null + "iets" = null Je zult dus null moeten vervangen door een lege string.

Als ik het mij goed kan herinneren gebruikt mysql de functie coalesce in plaats van isnull.

Een 3e oplossing is een case constructie, ik weet alleen niet of mysql dat ondersteund.

Verwijderd

Of een iif (immediate IF) in Access werkt dat in ieder geval. IIF(body1 IS NOT NULL, body1, "").

Verwijderd

Reveller schreef op zondag 11 februari 2007 @ 21:50:
[...]

SQL:
1
2
3
4
5
6
SELECT n. * , ISNULL(a.body, c.body) AS body, u.name
FROM nodes n
  LEFT JOIN articles a ON a.nid = n.nid
  LEFT JOIN comments c ON c.nid = n.nid
  LEFT JOIN users u ON u.uid = n.uid
WHERE n.type IN ('article', 'comment')


[...]

:?
Oh, mysql :+ . Daar werkt de ISNULL ietsjes anders :P

SQL:
1
COALESCE(a.body, c.body) as body


Dat zou wel moeten werken, dat geeft de eerste waarde terug die niet NULL is.

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Dan lees je dus MySQL manual: control flow functions en soortgelijke manual pagina's en vind je binnen 2 minuten de oplossing. ;)

{signature}


  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Dank iedereen! Met COALESCE is het gelukt :)

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."

Pagina: 1