Toon posts:

[SQL] laatste rij selecteren

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

Verwijderd

Topicstarter
Ik heb al op een aantal websites gekeken, maar ik kan het niet echt vinden:

Hoe kan ik de gegevens van de laatste rij in een tabel ophalen?

SELECT * FROM table WHERE id = ??maximaal??

Verwijderd

SELECT * FROM table ORDER BY id DESC LIMIT 1;

zoiets? :)

Verwijderd

Topicstarter
Okee, dank je...ik had misschien gedacht dat er een functie zou zijn voor de laatst toegevoegde rij...maar dit werkt ook :-)

Verwijderd

Volgens mij is dit de meest optimale manier om het te fixen. Uiteraard zijn er nog veel meer mogelijkheden.

Verwijderd

Ik denk dat:

SELECT MAX(Id) AS Maximum FROM Table

een stuk sneller zal zijn...

Verwijderd

Topicstarter
Het werkt trouwens niet, er zal nog ergens een kommaatje tussen moeten, maar ik kan niet echt een SQL reference vinden.

KoenM: Hoe krijg ik dan mijn gegevens van die rij?

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Over welke database software hebben we het?

  • robjanssen
  • Registratie: September 2001
  • Laatst online: 02-08 16:10

robjanssen

Software Developer

code:
1
2
3
SELECT *
FROM Table
WHERE ID = (SELECT MAX(ID) FROM TABLE)

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Op donderdag 20 juni 2002 19:25 schreef robjanssen het volgende:
code:
1
2
3
SELECT *
FROM Table
WHERE ID = (SELECT MAX(ID) FROM TABLE)
of
code:
1
2
3
SELECT top 1 *
FROM Table
Order by ID desc

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Verwijderd

Topicstarter
We hebben het over Oracle 9i.

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Op donderdag 20 juni 2002 21:55 schreef carens het volgende:
We hebben het over Oracle 9i.
Ah, volgende keer gelijk even noemen he ? :)

Maar dan is die ene met de subselect wel een leuke.

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 28-08 12:00

Janoz

Moderator Devschuur®

!litemod

Owh, en wat wordt de toepassing? Ik hoop niet de gegevens ophalen van de laatst ingevoegde rij omdat er bij de invoeg actie nog iets extra's gebeurt zou moeten worden...

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Verwijderd

Topicstarter
Ik ben tamelijk nieuw in dit gebied; ik heb die Oracle TechNet pagina bekeken, er staat een heleboel documentatie, maar nergens zie ik SQL Reference staan. Als ik zoek, dan krijg ik allemaal flarden SQL, ook niet echt wat ik zoek.

Maar die laatste rij selecteren is gelukt. Ik heb het eigenlijk alleen nodig om de id van de volgende rij te bepalen. Oracle kent geen auto_increment...ik heb ook gekeken naar triggers, maar dat lijkt mij niet veel uitmaken met gewoon het id opvragen en er een bij optellen.

  • DigiK-oz
  • Registratie: December 2001
  • Laatst online: 12:03
Op vrijdag 21 juni 2002 12:29 schreef carens het volgende:
Oracle kent geen auto_increment...
Oh ? En sequences dan ?

Whatever


Verwijderd

Op donderdag 20 juni 2002 21:55 schreef carens het volgende:
We hebben het over Oracle 9i.
Dan wordt het dus:

SELECT *
FROM Table
WHERE ROWID = (SELECT MAX(ROWID) FROM TABLE)
/

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Op vrijdag 21 juni 2002 12:29 schreef carens het volgende:
Oracle kent geen auto_increment...ik heb ook gekeken naar triggers, maar dat lijkt mij niet veel uitmaken met gewoon het id opvragen en er een bij optellen.
Sterker nog, mysql is de enige die dat _wel_ kent :)

Maarreuhm, dat met triggers maakt juist wel erg veel uit ;)
Zorgt er namelijk voor dat het niet fout 'kan' gaan, ipv niet fout 'hoort' te gaan :)
Op vrijdag 21 juni 2002 12:54 schreef rara het volgende:
Dan wordt het dus:
Die query is wel correct, maar niet voor deze toepassing ;)
Dan is "insert into ... values (sequence.next_val(), ...);"
(oid) nog beter.

  • Noork
  • Registratie: Juni 2001
  • Niet online
sequence is ongeveer hetzelfde als auto_increment ( access kent trouwens ook auto_increment, maar valt niet een DBMS te noemen)

  • TimMer
  • Registratie: Februari 2000
  • Niet online
Op vrijdag 21 juni 2002 12:54 schreef rara het volgende:

[..]

Dan wordt het dus:

SELECT *
FROM Table
WHERE ROWID = (SELECT MAX(ROWID) FROM TABLE)
/
Deze kun je toch herschrijven naar:
code:
1
2
3
4
SELECT *
FROM Table
WHERE ROWID = MAX(ROWID)
/

?

Je hoeft dan geen subselect uit te voeren, scheelt weer performance.

  • corani
  • Registratie: December 2000
  • Laatst online: 05-10-2017

corani

__,,,_(^_^)_,,,__

Let op:
Op donderdag 20 juni 2002 22:22 schreef Janoz het volgende:


Owh, en wat wordt de toepassing? Ik hoop niet de gegevens ophalen van de laatst ingevoegde rij omdat er bij de invoeg actie nog iets extra's gebeurt zou moeten worden...

Laat me nou toch eens met rust man!
Iedereen die in telekinese gelooft, steek a.u.b. mijn hand op


  • TimMer
  • Registratie: Februari 2000
  • Niet online
Op donderdag 20 juni 2002 17:23 schreef KoenM het volgende:
Ik denk dat:

SELECT MAX(Id) AS Maximum FROM Table

een stuk sneller zal zijn...
Dan pakt hij alleen de hoogste ID-code, niet de totale tupel.

  • Noork
  • Registratie: Juni 2001
  • Niet online
select top 1 * from table
order by ROWID desc;

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Op vrijdag 21 juni 2002 12:57 schreef Noork het volgende:
sequence is ongeveer hetzelfde als auto_increment ( access kent trouwens ook auto_increment, maar valt niet een DBMS te noemen)
Mwoh, ik zou ze toch niet hetzelfde noemen :)

De Serial oplossing in postgresql (die dus op de achtergrond een sequence aanmaakt) is dan even iets beter vergelijkbaar.

Een sequence moet je wel helemaal zelf toepassen verder.

  • raptorix
  • Registratie: Februari 2000
  • Laatst online: 17-02-2022
Op vrijdag 21 juni 2002 13:02 schreef ACM het volgende:

[..]

Mwoh, ik zou ze toch niet hetzelfde noemen :)

De Serial oplossing in postgresql (die dus op de achtergrond een sequence aanmaakt) is dan even iets beter vergelijkbaar.

Een sequence moet je wel helemaal zelf toepassen verder.
sqlserver kent trouwens ook autonummering hoor :)

Verwijderd

Deze kun je toch herschrijven naar:
code:
1
2
3
4
SELECT *
FROM Table
WHERE ROWID = MAX(ROWID)
/

?

Je hoeft dan geen subselect uit te voeren, scheelt weer performance.
[/quote]


SQL> l
1 select * from sub3_subjekt
2* where rowid=max(rowid)
SQL> /
where rowid=max(rowid)
*
ERROR at line 2:
ORA-00934: group function is not allowed here

  • TimMer
  • Registratie: Februari 2000
  • Niet online
Op vrijdag 21 juni 2002 13:06 schreef rara het volgende:
SQL> l
1 select * from sub3_subjekt
2* where rowid=max(rowid)
SQL> /
where rowid=max(rowid)
*
ERROR at line 2:
ORA-00934: group function is not allowed here
Ik snap niet helemaal hoe jouw code in elkaar steekt, leg eens uit?

Mijn code:
code:
1
SELECT *

Selecteer alle attributen
code:
1
FROM Table

Van de tabel Table
code:
1
WHERE ROWID = MAX(ROWID)

Waar het attribuut ROWID gelijk is aan de hoogste ROWID.
code:
1
/

Einde statement.

Dit lijkt mij een logische opbouw, zal wel aan mij liggen. Ik heb ook alleen pure SQL gehad, geen Transact-SQL of ander vormen van SQL.

Verwijderd

Op vrijdag 21 juni 2002 13:09 schreef TimMer het volgende:

[..]

Ik snap niet helemaal hoe jouw code in elkaar steekt, leg eens uit?

Mijn code:
code:
1
SELECT *

Selecteer alle attributen
code:
1
FROM Table

Van de tabel Table
code:
1
WHERE ROWID = MAX(ROWID)

Waar het attribuut ROWID gelijk is aan de hoogste ROWID.
code:
1
/

Einde statement.

Dit lijkt mij een logische opbouw, zal wel aan mij liggen. Ik heb ook alleen pure SQL gehad, geen Transact-SQL of ander vormen van SQL.
Ik heb het even op onze Oracle database getest.

SQL> l ==> even een list wat ik doe.
1 select * from sub3_subjekt
2* where rowid=max(rowid)
SQL> / ==> even runnen
where rowid=max(rowid)
*
ERROR at line 2:
ORA-00934: group function is not allowed here

Dit laatste is de Oracle foutmelding. Werkt dus niet.

  • Noork
  • Registratie: Juni 2001
  • Niet online
werkt deze wel:

select top 1 * from table
order by rowid asc/desc?

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Op vrijdag 21 juni 2002 13:09 schreef TimMer het volgende:
code:
1
WHERE ROWID = MAX(ROWID)

Waar het attribuut ROWID gelijk is aan de hoogste ROWID.
Je kan MAX() en al die functies volgens mij niet gebruiken in de Where clause want op het moment dat hij het vergelijkt weet hij nog niet wat de MAX is. Mischien dat een dbms het wel ondersteunt door automatisch een sub select te maken maar in standaard sql kan het niet

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • sverzijl
  • Registratie: Januari 2001
  • Laatst online: 19:04
Op vrijdag 21 juni 2002 13:15 schreef Noork het volgende:
werkt deze wel:

select top 1 * from table
order by rowid asc/desc?
Oracle kent de 'TOP' functie niet.

select * from table
where rowid=(select max(rowid) from table) is de minst slechte oplossing (t blijft een slechte implementatie als je zoiets nodig hebt, omdat er hiervoor altijd een full table danwel full index scan nodig is. nofi)

Verwijderd

Op vrijdag 21 juni 2002 13:18 schreef rwb het volgende:

[..]

Je kan MAX() en al die functies volgens mij niet gebruiken in de Where clause want op het moment dat hij het vergelijkt weet hij nog niet wat de MAX is. Mischien dat een dbms het wel ondersteunt door automatisch een sub select te maken maar in standaard sql kan het niet
/new2/centric/ghplus/gh2/gh/frm/afiedt.buf" 3 lines, 87 characters

1 select subjektnr from sub3_subjekt
2* where rowid=(select max(rowid) from sub3_subjekt)
SQL> /

SUBJEKTNR
----------
326346

Dit Werkt.

  • TimMer
  • Registratie: Februari 2000
  • Niet online
Op vrijdag 21 juni 2002 13:18 schreef rwb het volgende:

[..]

Je kan MAX() en al die functies volgens mij niet gebruiken in de Where clause want op het moment dat hij het vergelijkt weet hij nog niet wat de MAX is. Mischien dat een dbms het wel ondersteunt door automatisch een sub select te maken maar in standaard sql kan het niet
Deze indruk krijg ik ook na een aardige zoektocht op Google. Het wordt gewoon een subselect, het is niet anders.

  • corani
  • Registratie: December 2000
  • Laatst online: 05-10-2017

corani

__,,,_(^_^)_,,,__

ik heb verder geen ervaring met oracle.. maar kan dit niet?
code:
1
select * from table order by rowid desc limit 1

Laat me nou toch eens met rust man!
Iedereen die in telekinese gelooft, steek a.u.b. mijn hand op


  • TimMer
  • Registratie: Februari 2000
  • Niet online
Op vrijdag 21 juni 2002 13:21 schreef rara het volgende:

[..]

/new2/centric/ghplus/gh2/gh/frm/afiedt.buf" 3 lines, 87 characters

1 select subjektnr from sub3_subjekt
2* where rowid=(select max(rowid) from sub3_subjekt)
SQL> /

SUBJEKTNR
----------
326346

Dit Werkt.
Dan moet je dus deze gaan gebruiken:
code:
1
2
3
SELECT *
FROM sub3_subjekt
WHERE rowid = (SELECT MAX(rowid) FROM sub3_subjekt)

Verwijderd

Shiittt.. .zelfs MS Access kent Autonummering..

ga me niet vertellen dat Oracle dat niet ondersteund.
Ik niet snap!

  • sverzijl
  • Registratie: Januari 2001
  • Laatst online: 19:04
Op vrijdag 21 juni 2002 13:21 schreef rara het volgende:

[..]

/new2/centric/ghplus/gh2/gh/frm/afiedt.buf" 3 lines, 87 characters

1 select subjektnr from sub3_subjekt
2* where rowid=(select max(rowid) from sub3_subjekt)
SQL> /

SUBJEKTNR
----------
326346

Dit Werkt.
Ik neem aan dat je subjektnr (subjeKt ?) oplopend is. Waarom dan niet gewoon :
code:
1
2
3
4
5
6
Select * 
from  sub3_subjekt
where subjektnr = (
             select max(subjektnr) 
             from sub3subjekt
             )

Dan wordt er in ieder geval via index gezocht (aangenomen dat je subjektnr in je primary key zit danwel geindexeerd is natuurlijk:)

  • TimMer
  • Registratie: Februari 2000
  • Niet online
Op vrijdag 21 juni 2002 13:26 schreef -NW het volgende:
Shiittt.. .zelfs MS Access kent Autonummering..

ga me niet vertellen dat Oracle dat niet ondersteund.
Ik niet snap!
Waarom opeens die vraag? Voegt niet veel toe aan de discussie.

Verder: er is al gezegd dat sequences de tegenhanger zijn van auto_increment.

  • utlover
  • Registratie: Januari 2000
  • Laatst online: 31-08 15:08
Je moet dan ook geen rij operaties (select *D en kolom operaties (max) in een statement willen combineren. De beschreven oplossing met subselect is juist.

Sequences:

select [sequence_naam].curval voor de huidige waarde van van de nummering


select [sequence_naam].nextval voor een opgehoogde waarde van van de nummering

  • sverzijl
  • Registratie: Januari 2001
  • Laatst online: 19:04
Op vrijdag 21 juni 2002 13:26 schreef -NW het volgende:
Shiittt.. .zelfs MS Access kent Autonummering..

ga me niet vertellen dat Oracle dat niet ondersteund.
Ik niet snap!
tuurlijk wel, maar met Oracle zul je dit moeten implementeren met zgn sequences.

bijv:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
SQL> create sequence tellertje
  2  start with 1 increment by 1;

Sequence created.

SQL> 
SQL> select tellertje.nextval from dual;

   NEXTVAL
----------
       1

SQL> /

   NEXTVAL
----------
       2

  • TimMer
  • Registratie: Februari 2000
  • Niet online
Op vrijdag 21 juni 2002 13:26 schreef sverzijl het volgende:

[..]

Ik neem aan dat je subjektnr (subjeKt ?) oplopend is. Waarom dan niet gewoon :
code:
1
2
3
4
5
6
Select * 
from  sub3_subjekt
where subjektnr = (
             select max(subjektnr) 
             from sub3subjekt
             )

Dan wordt er in ieder geval via index gezocht (aangenomen dat je subjektnr in je primary key zit danwel geindexeerd is natuurlijk:)
Het enige verschil met deze code:
code:
1
2
3
SELECT *
FROM sub3_subjekt
WHERE rowid = (SELECT MAX(rowid) FROM sub3_subjekt)

is dat je subjectnr gaat gebruiken. Waarom zou je rowid niet gebruiken? Die is al primary key maak ik op uit het verhaal van de topicstarter.

  • sverzijl
  • Registratie: Januari 2001
  • Laatst online: 19:04
Op vrijdag 21 juni 2002 13:29 schreef TimMer het volgende:

[..]

Het enige verschil met deze code:
code:
1
2
3
SELECT *
FROM sub3_subjekt
WHERE rowid = (SELECT MAX(rowid) FROM sub3_subjekt)

is dat je subjectnr gaat gebruiken. Waarom zou je rowid niet gebruiken? Die is al primary key maak ik op uit het verhaal van de topicstarter.
ROWID is een zgn 'pseudo-kolom' in Oracle. Iedere tabel heeft um, maar het is bad-practice om hierop te selecteren. Daarnaast zul je zien dat selecteren op een geindexeerde kolom vele malen sneller is dan gebruik maken van ROWID in een MIN/MAX select bijv.
(Er zijn nog meer nadelen bij gebruik van ROWID, maar dat terzijde.)

  • DigiK-oz
  • Registratie: December 2001
  • Laatst online: 12:03
Maar de ellende is niet te overzien als er meerdere users gebruik hiervan maken. Als er maar twee tegelijkertijd de 'hoogste' key opvragen, vervolgens allebei met eenzelfde nieuwe key willen gaan inserten...Brrrrr

Sequences, eventueel automatisch toegevoegd in een before_insert trigger, zijn daarentegen wel veilig. Oke, wat meer werk, maar fouten opsporen die door committed/uncommitted transacties worden veroorzaakt, is echt nog veel meer werk.

Ik zou het alleen zonder sequences doen als je zeker weet dat er altijd maar 1 user gebruik maakt van deze applicatie/database...

Whatever


  • Goodielover
  • Registratie: November 2001
  • Laatst online: 18-08 11:34

Goodielover

Only The Best is Good Enough.

Je gebruikt dus een Oracle database.
Oplossing:
1. creeer een tabel met een numeriek PK
2. creeer een cyclische sequence pk_tabel met als max waarde de maximaal toegestane waarde van de PK.
3. Maak een stored proc met daarin de volgende code
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
select pk_tabel.nextval
into   temp_var
from   dual;

BEGIN
  WHILE 1=1
  DO
    select pk_tabel.nextval
    into   temp1
    from   tabel
    where  pk = temp_var;
    temp_var := temp1;
  ENDWHILE
EXCEPTION when no_data_found
  then /* waarde wordt nog niet gebruikt */
END

Deze proc laat je dan de waarde van temp_var terug geven als key.
Het loopje zorgt ervoor dat je de nummering opnieuw kan laten beginnen bij 1 (of 0) en dat hij zelf de gaten vindt in de nummering.
Dit nummer gebruik je dan om te inserten. de sequence zorgt ervoor dat twee opvragingen na elkaar ieder een volgnd nummer krijgen ondanks dat de transactie nog niet beeindigd is.
suc6

PS vergeet al die oplossingen met ROWID = MAX() die zin syntaktisch onzin en bovendien moet je nooit de rowid gebruiken. Die is voor Oracle intern kan ook veranderen voor een record in de tijd. Een hogere ROWID zegt ook niets over het tijdstip van insert, maar over de fysieke locatie van het record.

  • sverzijl
  • Registratie: Januari 2001
  • Laatst online: 19:04
Op vrijdag 21 juni 2002 13:38 schreef sjis het volgende:

Ik zou het alleen zonder sequences doen als je zeker weet dat er altijd maar 1 user gebruik maakt van deze applicatie/database...
Het kan ook eventueel nog zonder sequences. Gebruik een 'teller-tabel' waarin je de huidige waarde van een bepaalde teller opslaat. Laat de applicatie de row met exclusive lock openen en verhoog het nummer met 1. Sluit de cursor waardoor de 'teller' weer wordt vrijgegeven voor andere applicaties/gebruikers. De tijd dat de cursor met for update geopend is moet dan wel zeer klein zijn om te voorkomen dat users/applicaties op elkaar moeten wachten tot de lock wordt vrijgegeven.

Sequences is makkelijker, maar voor RDBMS-en die geen auto-increment/sequences hebben, maar wel een geavanceerd (row)-locking mechanisme (bijv DB2) werkt dit ook.

Verwijderd

Op vrijdag 21 juni 2002 13:15 schreef Noork het volgende:
werkt deze wel:

select top 1 * from table
order by rowid asc/desc?
1 select top 1 * from sub3_subjekt
2* order by rowid desc
SQL> /
select top 1 * from sub3_subjekt
*
ERROR at line 1:
ORA-00923: FROM keyword not found where expected

Verwijderd

Op vrijdag 21 juni 2002 13:26 schreef sverzijl het volgende:

[..]

Ik neem aan dat je subjektnr (subjeKt ?) oplopend is. Waarom dan niet gewoon :
code:
1
2
3
4
5
6
Select * 
from  sub3_subjekt
where subjektnr = (
             select max(subjektnr) 
             from sub3subjekt
             )

Dan wordt er in ieder geval via index gezocht (aangenomen dat je subjektnr in je primary key zit danwel geindexeerd is natuurlijk:)
Je hebt helemaal gelijk zo kan het ook. Echter er bestaat een subjektnr met het nummer 9999999999 en dat is het subjekt "leegstand". Dit is het resultaat:


1 Select subjektnr
2 from sub3_subjekt
3 where subjektnr = (
4 select max(subjektnr)
5 from sub3_subjekt
6* )
SQL> /

SUBJEKTNR
----------
9999999999

Verder is het veld subjektnr wel een sequence die bij vastleggen van een nieuw subjekt het nummer 1 ophoogt, maar in dit geval is er een speciaal subjektnr met waarde 999999999.

Verwijderd

"/new2/centric/ghplus/gh2/gh/frm/afiedt.buf" 5 lines, 79 characters

1 Select subjektnr
2 from sub3_subjekt
3 where rownum <10
4* order by subjektnr desc
SQL> /

SUBJEKTNR
----------
9999999999
326347
326346
326345
326344
326343
326342
326341
326340

9 rows selected.

Je ziet dat er een groot gat is tussen het subjektnr 999999999 en het een a hoogste subjektnr(326347) dat bij het vastleggen van een nieuw subjekt met 1 opgehoogd wordt.

  • Goodielover
  • Registratie: November 2001
  • Laatst online: 18-08 11:34

Goodielover

Only The Best is Good Enough.

code:
1
2
3
4
5
6
7
Select subjektnr
from  sub3_subjekt
where subjektnr = (
             select max(subjektnr)
             from sub3_subjekt
             where subjektnr < 9999999999
            )

moeilijk doen is ook een kunst
Pagina: 1