[SQL] kom er niet uit ;(

Pagina: 1
Acties:

  • oZy
  • Registratie: Juli 2001
  • Laatst online: 28-08 16:38
tabel_1:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/---------------------------\
| id | fk_1 | fk_2 | datum  |
-----------------------------
|  1 |    1 |    1 | 1-4-02 |
|  2 |    1 |    2 | 1-5-02 |
|  3 |    1 |    3 | 1-6-02 |
|  4 |    2 |    1 | 2-4-02 |
|  5 |    2 |    4 | 2-5-02 |
|  6 |    3 |    1 | 3-4-02 |
|  7 |    4 |    1 | 4-4-02 |
|  8 |    4 |    3 | 4-6-02 |
|  9 |    5 |    1 | 5-4-02 |
| 10 |    5 |    2 | 5-5-02 |
\---------------------------/


wat ik wil hebben:
code:
1
2
3
4
SELECT   id
FROM     tabel_1
WHERE    ** datum = max **
GROUP BY fk_1

de WHERE statement is natuurlijk onzin, maar dit om aan te geven waar ik naar zoek. Ik wil dus de ID's hebben waar de datum het hoogst is, per fk_1.

ik zit al de hele tijd te tobben met sub selects, maar ik loop steeds tegen muren op :'( iemand een ideetje?

tis MS SQL Server trouwens..

PS, het gewenste resultaat in dit geval is dus 3, 5, 6, 8, 10.

  • whoami
  • Registratie: December 2000
  • Laatst online: 19:34
code:
1
WHERE datum in (SELECT MAX(datum) FROM tabel)


Hier ga je de id's krijgen van de records die de hoogste datum hebben.
Wil je bv de id's van de hoogste 5 datums dan moet je het als volgt doen:
code:
1
WHERE datum in ( SELECT TOP 5 datum FROM tabel ORDER BY datum DESC)

https://fgheysels.github.io/


  • oZy
  • Registratie: Juli 2001
  • Laatst online: 28-08 16:38
code:
1
2
3
4
5
SELECT  id
FROM        tabel_1 
WHERE   datum IN ( SELECT   max(datum)
           FROM     tabel_1
           GROUP BY fk_1 )

dan loop je vast op dingen die dezelfde datum hebben. je moet dus voor de volledigheid testen op WHERE id IN, maar dan kom je weer bij dezelfde vraag.. hoe krijg je alle ID's waar de datum het hoogst is per fk_1.

SELECT MAX(datum) FROM tabel geeft trouwens alleen de hoogste datum in de hele tabel terug, daar heb je niets aan in dit geval.

Verwijderd

Hier heb je een oplossing die onder Sybase werkt

select id, fk_1
from a table_x
where datum = (select max(datum)
from a table_y
where table_y.fk_1 = table_x.fk_1)

Succes ermee

Verwijderd

Verwijderd schreef op 29 oktober 2002 @ 12:22:
Hier heb je een oplossing die onder Sybase werkt

select id, fk_1
from tabel_1 table_x
where datum = (select max(datum)
from tabel_1 table_y
where table_y.fk_1 = table_x.fk_1)

Succes ermee

  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
Als ik je probleem goed begrepen heb, dan zijn genoemde queries volgens mij toch niet (helemaal) juist. Je zoekt per fk_1 het record met de nieuwste datum en dat doen de gegeven oplossingen niet.
Voorstel:
code:
1
2
3
4
SELECT  id
FROM    tabel_1 t
JOIN    (SELECT fk_1, MAX (datum) as MaxDatum GROUP BY fk_1)
    AS Sub ON (Sub.fk_1 = t.fk_1 AND Sub.MaxDatum = t.datum)

Never underestimate the power of


Verwijderd

cameodski schreef op 29 oktober 2002 @ 12:42:
Als ik je probleem goed begrepen heb, dan zijn genoemde queries volgens mij toch niet (helemaal) juist. Je zoekt per fk_1 het record met de nieuwste datum en dat doen de gegeven oplossingen niet.
Voorstel:
code:
1
2
3
4
SELECT  id
FROM    tabel_1 t
JOIN    (SELECT fk_1, MAX (datum) as MaxDatum GROUP BY fk_1)
    AS Sub ON (Sub.fk_1 = t.fk_1 AND Sub.MaxDatum = t.datum)
Dus die van mij zou het niet doen? Ik weet wel zeker dat die query van mij juist is.

Mocht mijn oplossing onjuist zijn, kun je me dan uitleggen waarom het juiste antwoord uitkomt?

select id, fk_1
from tabel_1 x
where datum = (select max(datum)
from tabel_1 y
where y.fk_1 = x.fk_1)
id fk_1
[int] [int]
----- -----
3 1
5 2
6 3
8 4
10 5

  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
Verwijderd schreef op 29 oktober 2002 @ 12:54:
[...]


Dus die van mij zou het niet doen? Ik weet wel zeker dat die query van mij juist is.

Mocht mijn oplossing onjuist zijn, kun je me dan uitleggen waarom het juiste antwoord uitkomt?

select id, fk_1
from tabel_1 x
where datum = (select max(datum)
from tabel_1 y
where y.fk_1 = x.fk_1)
id fk_1
[int] [int]
----- -----
3 1
5 2
6 3
8 4
10 5
Ja dat kan ik. Doordat de datum nu toevallig in de hele tabel uniek is, geeft ie het gewenste resultaat, maar zo gauw als dat niet meer het geval is, kun je hele vreemde resultaten verwachten.

Never underestimate the power of


Verwijderd

cameodski schreef op 29 oktober 2002 @ 12:58:
[...]

Ja dat kan ik. Doordat de datum nu toevallig in de hele tabel uniek is, geeft ie het gewenste resultaat, maar zo gauw als dat niet meer het geval is, kun je hele vreemde resultaten verwachten.
Beste Cameodski, uit voorgaande topics weet ik dat je best veel afweet van SQL. ;)

Ik hoef je derhalve ook niet uit te leggen dat in oZy zijn voorbeeld data van de onderstaande rijen geselecteerd worden.
| id | fk_1 | fk_2 | datum |
-----------------------------
| 3 | 1 | 3 | 1-6-02 |
| 5 | 2 | 4 | 2-5-02 |
| 6 | 3 | 1 | 3-4-02 |
| 8 | 4 | 3 | 4-6-02 |
| 10 | 5 | 2 | 5-5-02 |


Inderdaad, in het geval dat er fk_1 zijn waarvoor geldt, dat de maximale datums vaker voorkomt, zal dan ook vaker een id worden weergegeven.

Indien oZy zijn oorspronkelijke tabel er als volgt had uitgezien
| id | fk_1 | fk_2 | datum |
-----------------------------
| 1 | 1 | 1 | 1-6-02 |
| 2 | 1 | 2 | 1-5-02 |
| 3 | 1 | 3 | 1-6-02 |
| 4 | 2 | 1 | 2-4-02 |
| 5 | 2 | 4 | 2-5-02 |
| 6 | 3 | 1 | 3-4-02 |
| 7 | 4 | 1 | 4-4-02 |
| 8 | 4 | 3 | 4-6-02 |
| 9 | 5 | 1 | 5-4-02 |
| 10 | 5 | 2 | 5-5-02 |


dan was het volgende uitgekomen
| id | fk_1 | fk_2 | datum |
-----------------------------
| 1 | 1 | 1 | 1-6-02 |
| 3 | 1 | 3 | 1-6-02 |
| 5 | 2 | 4 | 2-5-02 |
| 6 | 3 | 1 | 3-4-02 |
| 8 | 4 | 3 | 4-6-02 |
| 10 | 5 | 2 | 5-5-02 |


Volledig met je eens.

Even afwachten of oZy het probleem wat verder kan uitleggen, want als hij per fk_1 maar maximaal 1 id wil terugkrijgen, zal de query verder moeten worden uitgebreid.

  • Annie
  • Registratie: Juni 1999
  • Laatst online: 25-11-2021

Annie

amateur megalomaan

cameodski schreef op 29 oktober 2002 @ 12:58:
[...]

Ja dat kan ik. Doordat de datum nu toevallig in de hele tabel uniek is, geeft ie het gewenste resultaat, maar zo gauw als dat niet meer het geval is, kun je hele vreemde resultaten verwachten.
Bovendien lijkt mij de oplossing met de correlative subquery trager.

Today's subliminal thought is:


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 22-06 10:32

_Thanatos_

Ja, en kaal

Mensen, kom op, dit is toch heel simpel?

code:
1
2
3
SELECT fk_1, MAX(datum)
FROM tabel_1
GROUP BY fk_1

Zoiets zou je dan terug krijgen:
code:
1
2
3
4
5
6
7
8
9
/---------------\
| fk_1 | datum  |
-----------------
|    1 | 1-6-02 |
|    2 | 2-5-02 |
|    3 | 3-4-02 |
|    4 | 4-6-02 |
|    5 | 5-5-02 |
\---------------/

Dat wil je toch :?

日本!🎌


Verwijderd

Hij wil de ID's hebben en niet de fk_1 :)

  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
Verwijderd schreef op 29 oktober 2002 @ 13:18:
Beste Cameodski, uit voorgaande topics weet ik dat je best veel afweet van SQL. ;)
Bedankt voor het compliment, maar bij nader inzien, moet ik toegeven dat ik me vergist heb. |:(
Ik had onderstaande filter in de subquery even over het hoofd gezien:
code:
1
where y.fk_1 = x.fk_1

Maar subqueries die een filter hebben op basis van een veld uit bovenliggende query zijn op zijn minst niet zo netjes en ook niet zo snel. Die gebruik ik dus ook zo weinig mogelijk. Vandaar dat ik hem eventjes over het hoofd zag.
Annie schreef op 29 oktober 2002 @ 13:21:
Bovendien lijkt mij de oplossing met de correlative subquery trager.
Subqueries waarin dergelijke filters voorkomen, zijn inderdaad niet erg goed voor de performance, omdat de subquery per record in de "hoofdquery" uitgevoerd moet worden.

Never underestimate the power of


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
_Thanatos_ schreef op 29 oktober 2002 @ 13:27:
Mensen, kom op, dit is toch heel simpel?

code:
1
2
3
SELECT fk_1, MAX(datum)
FROM tabel_1
GROUP BY fk_1
Het lijkt wel alsof je een gedeelte van mijn query hebt overgenomen. :)
Je had beter de hele query over kunnen nemen. :)

Never underestimate the power of


Verwijderd

_Thanatos_ schreef op 29 oktober 2002 @ 13:27:
Mensen, kom op, dit is toch heel simpel?

code:
1
2
3
SELECT fk_1, MAX(datum)
FROM tabel_1
GROUP BY fk_1

Zoiets zou je dan terug krijgen:
code:
1
2
3
4
5
6
7
8
9
/---------------\
| fk_1 | datum  |
-----------------
|    1 | 1-6-02 |
|    2 | 2-5-02 |
|    3 | 3-4-02 |
|    4 | 4-6-02 |
|    5 | 5-5-02 |
\---------------/

Dat wil je toch :?
Nee, uit oZy zijn vraagstelling is af te leiden dat oZy per attribuut fk_1 het attribuut ID opvragen, waarvoor geldt dat attribuut datum het hoogst is.

Jouw voorbeeld geeft per fk_1 de hoogste datum terug.

(zie ook Cameodski zijn antwoord voor uitleg) In geval dat er per fk_1 meerdere records zijn die de maximale datum bevatten (gegroepeerd per fk_1), er per fk_1 meerdere ID teruggegeven worden.

Verwijderd

cameodski schreef op 29 oktober 2002 @ 13:33:
[...]

Bedankt voor het compliment, maar bij nader inzien, moet ik toegeven dat ik me vergist heb. |:(
Ik had onderstaande filter in de subquery even over het hoofd gezien:
code:
1
where y.fk_1 = x.fk_1

Maar subqueries die een filter hebben op basis van een veld uit bovenliggende query zijn op zijn minst niet zo netjes en ook niet zo snel. Die gebruik ik dus ook zo weinig mogelijk. Vandaar dat ik hem eventjes over het hoofd zag.

[...]

Subqueries waarin dergelijke filters voorkomen, zijn inderdaad niet erg goed voor de performance, omdat de subquery per record in de "hoofdquery" uitgevoerd moet worden.
Inderdaad, dergelijke queries vermijd ik ook liever in produktie omgevingen.

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 22-06 10:32

_Thanatos_

Ja, en kaal

code:
1
2
3
4
5
6
7
SELECT tabel_1.ID, x.*
FROM (
   SELECT fk_1, MAX(datum)
   FROM tabel_1
   GROUP BY fk_1
) AS x, tabel_1
WHERE x.fk_1=tabel_1.fk_1


Zoiets dan? (niet getest)
Kan ook best zijn dat je een ander soort JOIN moet gebruiken, maar volgens mij moet dit soort constructie wel werken...

日本!🎌


Verwijderd

Laat maar....

[ Voor 0% gewijzigd door Verwijderd op 29-10-2002 21:42 . Reden: Dit geeft 3, 5, 6, 8, 10 ]


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
_Thanatos_ schreef op 29 oktober 2002 @ 19:58:
code:
1
2
3
4
5
6
7
SELECT tabel_1.ID, x.*
FROM (
   SELECT fk_1, MAX(datum)
   FROM tabel_1
   GROUP BY fk_1
) AS x, tabel_1
WHERE x.fk_1=tabel_1.fk_1


Zoiets dan? (niet getest)
Kan ook best zijn dat je een ander soort JOIN moet gebruiken, maar volgens mij moet dit soort constructie wel werken...
Ga hem toch maar eens testen dan en je zult zien dat ie niet werkt.
En misschien is het ook wel handig als je eerst even de eerdere posts bestudeerd. :)

Never underestimate the power of


  • oZy
  • Registratie: Juli 2001
  • Laatst online: 28-08 16:38
Verwijderd schreef op 29 oktober 2002 @ 13:18:
[...]
Even afwachten of oZy het probleem wat verder kan uitleggen, want als hij per fk_1 maar maximaal 1 id wil terugkrijgen, zal de query verder moeten worden uitgebreid.
Inderdaad, maximaal 1 id. Ik heb nu de query van cameodski gebruikt, en die komt goed in de richting. Het is wel zo dat de qeury niet 100% sluitend is, aangezien je met dubbele datum's, meerdere id's (per fk_1) terug krijgt, en dat is niet de bedoeling.

Maar aangezien het datum veld een timestamp is (met miliseconden dus), is het zeker niet aannemelijk dat er ooit een dubbele timestamp in zal komen.

Let wel, ik vind dit vreselijk om een niet sluitende oplossing te gebruiken, absoluut niet netjes, maar it works for now.. bedankt voor het meedenken in ieder geval!

  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
oZy schreef op 30 oktober 2002 @ 10:33:
[...]

Inderdaad, maximaal 1 id. Ik heb nu de query van cameodski gebruikt, en die komt goed in de richting. Het is wel zo dat de qeury niet 100% sluitend is, aangezien je met dubbele datum's, meerdere id's (per fk_1) terug krijgt, en dat is niet de bedoeling.

Maar aangezien het datum veld een timestamp is (met miliseconden dus), is het zeker niet aannemelijk dat er ooit een dubbele timestamp in zal komen.

Let wel, ik vind dit vreselijk om een niet sluitende oplossing te gebruiken, absoluut niet netjes, maar it works for now.. bedankt voor het meedenken in ieder geval!
Er is dus eigenlijk niets uniek. Wat je dan zou kunnen doen is groeperen op fk_1 en datum in je hoofdquery en dan SELECT MAX (id) doen. Je krijgt dan het volgende:
code:
1
2
3
4
5
SELECT  id = MAX (t.id)
FROM    tabel_1 t
JOIN    (SELECT fk_1, MAX (datum) as MaxDatum GROUP BY fk_1)
    AS Sub ON (Sub.fk_1 = t.fk_1 AND Sub.MaxDatum = t.datum)
GROUP BY t.fk_1, t.datum
[/quote]

Never underestimate the power of

Pagina: 1