[SQL] waarde opzoeken in zichzelf zonder LEFT OUTER JOIN

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • njitter
  • Registratie: Oktober 2000
  • Niet online
De tabel is iets versimpeld maar het gaat om het volgende:

Ik moet labels printen voor klimaatkasten. Hierop staat het path (/1/) en de environment. De database is zo opgesteld dat enkel op het hoogste nivo de environment is vastgelegd. In het systeem selecteer ik een aantal posities om te printen waarna er een bestand wordt aangemaakt voor het labelprintprogramma.

Ik wil dat overal een environment komt te staan in de output. Kan dit zonder een join aan te maken met zichzelf (wat een extra kolom oplevert).

Query:
SQL:
1
2
3
4
select 
  unitid, environment, path
from storageunit
where unitid in ('SU-001', SU-002', 'SU-003', 'SU-004')


Output:

unitidunittypeenvironmentpathparentid
SU-001CabinetFreezer/1/
SU-002Shelf/1/1SU-001
SU-003Shelf/1/2SU-001
SU-004Shelf/1/3SU-001

Beste antwoord (via njitter op 08-05-2019 15:24)


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
njitter schreef op woensdag 8 mei 2019 @ 14:12:
tweede werkt inderdaad. Weer wat geleerd vandaag.

SQL:
1
 case when su.parentid is not null then psu.storageenvid else su.storageenvid END as storageenvid,
Volgens mij moet de eerste dan ook werken:

SQL:
1
coalesce(psu.storageenvid, su.storageenvid) as storageenvid

Coalesce selecteert de eerste non-null value uit de argumenten.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij

Alle reacties


Acties:
  • 0 Henk 'm!

  • emnich
  • Registratie: November 2012
  • Niet online

emnich

kom je hier vaker?

Zonder sub query of join lukt dat niet maar dat betekent niet dat het een extra kolom op hoeft te leveren. Je kan bijv een IF functie gebruiken om te bepalen welke environment je wilt laten zien. Bijvoorbeeld als de environment leeg is, laat je de environment uit de join zien.

Acties:
  • 0 Henk 'm!

  • njitter
  • Registratie: Oktober 2000
  • Niet online
OK. En hoe pas ik die IF dan in de JOIN?

Query:
SQL:
1
2
3
4
5
6
7
8
select 
  su.unitid, 
  su.environment, 
  psu.environment
  su.path 
  su.parentid
from storageunit as su left outer join storageunit as psu on psu.unitid = su.parentid
where unitid in ('SU-001', SU-002', 'SU-003', 'SU-004')

Acties:
  • 0 Henk 'm!

  • emnich
  • Registratie: November 2012
  • Niet online

emnich

kom je hier vaker?

Ik weet niet welke database je gebruikt dus daar kan nog wel wat verschil in zitten. En het is vooral niet mijn bedoeling om jouw code te gaan schrijven.

Heb je nu zelf al gezocht op bijvoorbeeld 'SQL IF statement'? En zo ja, waar loop je dan op vast.

Acties:
  • 0 Henk 'm!

  • njitter
  • Registratie: Oktober 2000
  • Niet online
SQL Server 2012

Acties:
  • 0 Henk 'm!

  • Christoxz
  • Registratie: Maart 2014
  • Laatst online: 11-09 07:24
Google is op "SQL IF" & "SQL Case".
Genoeg over te vinden hoe het werkt en hoe het toe te passen is.

T.Net Creality 3D Printer Discord


Acties:
  • 0 Henk 'm!

  • Megajr
  • Registratie: Mei 2005
  • Laatst online: 03-12-2024
Bij de output die je wilt denk ik direct aan recursieve CTE. Daar zit wel een join in op dat moment maar het levert geen extra kolom op.

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
njitter schreef op woensdag 8 mei 2019 @ 08:41:
Ik wil dat overal een environment komt te staan in de output. Kan dit zonder een join aan te maken met zichzelf (wat een extra kolom oplevert).
De fout zit hem erin dat je denkt dat een join met zichzelf een extra kolom oplevert, dat is onzin.
Jij bepaalt gewoon in je select wat je output kolommen zijn.

Acties:
  • 0 Henk 'm!

  • njitter
  • Registratie: Oktober 2000
  • Niet online
Gomez12 schreef op woensdag 8 mei 2019 @ 13:23:
[...]

De fout zit hem erin dat je denkt dat een join met zichzelf een extra kolom oplevert, dat is onzin.
Jij bepaalt gewoon in je select wat je output kolommen zijn.
ik kan ze wel anders noemen maar als ik twee keer dezelfde naam gebruik dan komt er toch echt een _1 achter bij een JOIN

Acties:
  • +1 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
De vraag is: waarom zou je twee keer dezelfde naam gebruiken ;) Wat @Gomez12 zegt klopt gewoon hoor.

[ Voor 23% gewijzigd door RobIII op 08-05-2019 13:43 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • njitter
  • Registratie: Oktober 2000
  • Niet online
RobIII schreef op woensdag 8 mei 2019 @ 13:42:
De vraag is: waarom zou je twee keer dezelfde naam gebruiken ;) Wat @Gomez12 zegt klopt gewoon hoor.
Ik wil maar 1 kolom in mn output.

Maar goed, als niemand iets concreets wil toevoegen dan mag het dicht.

Acties:
  • +1 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
njitter schreef op woensdag 8 mei 2019 @ 13:45:
[...]


Ik wil maar 1 kolom in mn output.
Dan select je er maar 1?

Je lijkt niet te begrijpen dat wat je select los staat van je joins of whatever (behalve dan dat je natuurlijk niets kan selecten dat niet in je from / joins staat uiteraard).

Wat jij wil is een conditionele value selecten; iets als "if (x then y else z) as kolom". Daarvoor kun je kijken naar o.a. de Case zoals al eerder aangekaart. Of Coalesce.

In jouw geval wordt 't dus iets als:
SQL:
1
2
select coalesce(psu.iets, su.iets) as iets, ..., ...
from ...
of
SQL:
1
2
select case when x > y then psu.iets else su.iets end as iets, ..., ...
from ...
njitter schreef op woensdag 8 mei 2019 @ 13:45:

Maar goed, als niemand iets concreets wil toevoegen dan mag het dicht.
Een slotje is niet nodig op een topic als je je oplossing hebt (of als de reacties je niet aantaan :/ ). Zie daarvoor ook onze faq betreffende topiceinde.

[ Voor 63% gewijzigd door RobIII op 08-05-2019 13:55 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • njitter
  • Registratie: Oktober 2000
  • Niet online
tweede werkt inderdaad. Weer wat geleerd vandaag.

SQL:
1
 case when su.parentid is not null then psu.storageenvid else su.storageenvid END as storageenvid,

[ Voor 8% gewijzigd door njitter op 08-05-2019 14:13 ]


Acties:
  • Beste antwoord
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
njitter schreef op woensdag 8 mei 2019 @ 14:12:
tweede werkt inderdaad. Weer wat geleerd vandaag.

SQL:
1
 case when su.parentid is not null then psu.storageenvid else su.storageenvid END as storageenvid,
Volgens mij moet de eerste dan ook werken:

SQL:
1
coalesce(psu.storageenvid, su.storageenvid) as storageenvid

Coalesce selecteert de eerste non-null value uit de argumenten.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • njitter
  • Registratie: Oktober 2000
  • Niet online
Dat werkt inderdaad ook. Ziet er wel iets netter uit :)

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Aangezien je toch SQL server gebruikt heb je ook nog isnull, die ikzelf altijd handiger vind omdat het eruitkomende type makkelijker te bepalen is...

Maar aan de andere kant hebben we ook projecten waar coalesce verplicht is omdat dat de standaard is :)

Oftewel je hebt nog keuze ook.

MSDN: Differences between ISNULL and COALESCE – SQL Server Engine Tips
Pagina: 1