Avatar billede ostehamster Nybegynder
19. april 2010 - 16:35 Der er 2 kommentarer og
1 løsning

Sammensat view

Hej

Jeg arbejder på et system, hvor en masse items kan have forskellige revisioner. For overskuelighedens skyld er det lige simplificeret til:

+------+----+-----+
| name | id | rev |
+------+----+-----+
| foo  |  1 |  1 |
| foo  |  2 |  2 |
| foo  |  3 |  3 |
| bar  |  4 |  1 |
+------+----+-----+

Dvs. tabeller har kun to "unikke" items, nemlig foo og bar, men foo har så tre forskellige revisioner.

Jeg ønsker nu at få alle unikke items, men kun den nyeste revision. id'erne for dette kan findes med

SELECT max( id ) as uid FROM test GROUP BY name

Dette kan så med INNER JOIN bruges til at finde hele alle de nyeste records
SELECT * FROM test INNER JOIN (
  SELECT max( id ) AS uid FROM test GROUP BY name
)tmp ON tmp.uid = test.id

Det virker også ganske glimrende. Eneste problem er, at det ikke kan laves til et view fordi:
"#1349 - View's SELECT contains a subquery in the FROM clause"

Det kan man så omgås ved at lave et view der hedder "unique_ids" med
SELECT max( id ) as uid FROM test GROUP BY name
og et andet der hedder "unique_items" med
SELECT * FROM test JOIN unique_ids tmp ON ( tmp.uid = test.id )

Dette virker glimrende på forskellige database, men på den server det skal køre, får jeg denne/disse fejl:
- SELECT command denied to user 'xxxx'@'%' for column 'uid' in table 'unique_ids'
- View 'Testdb_unique_items' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them

Den eneste forskel jeg lige kan se, er at på produktionsserveren er det root der har oprettet databasen, mens det på mine to test systemer er mig der har oprettet databasen.

Jeg har på test systemerne prøvet at oprette views både som bruger og som root, og begge dele virker.

Som bruger har jeg "GRANT ALL PRIVILEGES ON "test".* TO 'user'@'%'"

Nogen forslag til hvad problemet kan være? Eller evt. en mere elegant løsning end at snyde databasen ved at bruge to views :)

På forhånd tak
Christoffer
Avatar billede arne_v Ekspert
19. april 2010 - 18:33 #1
Hvad med:

SELECT * FROM test t1 WHERE rev = (SELECT MAX(rev) FROM test t2 WHERE t2.name = t1.name)

?
Avatar billede ostehamster Nybegynder
20. april 2010 - 01:33 #2
Snedigt :)

Takker for hjælpen... svar?
Avatar billede arne_v Ekspert
20. april 2010 - 01:38 #3
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester