[SQL] Subquery in FROM clausule

Pagina: 1
Acties:

  • ^Mo^
  • Registratie: Januari 2001
  • Laatst online: 04-11-2025
Hoi,

Ik heb de volgende query:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
SELECT
    MinPostings.Topic
FROM
    (
        SELECT
            MSG1.*
        FROM
            Messages AS MSG1
        WHERE
            MSG1.ID IN
            (
                SELECT
                    MIN(MSG2.ID)
                FROM
                    Messages AS MSG2
                GROUP BY
                    MSG2.Topic
            )
    ) AS MinPostings,
    (
        SELECT
            MSG3.*
        FROM
            Messages AS MSG3
        WHERE
            MSG3.ID IN
            (
                SELECT
                    MAX(MSG4.ID)
                FROM
                    Messages AS MSG4
                GROUP BY
                    MSG4.Topic
            )
    ) AS MaxPostings

Als ik het MaxPostings gedeelte weglaat, dan krijg ik prima de topic titles terug, 10 stuks. Zodra ik het MaxPostings gedeelte erbij pak, krijg ik alles 10 keer terug, dus in totaal 100 resultaten. Ik heb eigenlijk geen idee hoe het komt... mijn idee van wat er zou moeten gebeuren is dat de query van MinPostings een set resultaten teruggeeft van alle minimum ID's gegroepeerd op topic, en daarnaast zo'n zelfde soort resultset, maar dan gebasseerd op de maximum ID's... kennelijk gebeurd dit niet en begrijp ik het dus ook niet :(

"There are 10 kinds of people in the world, those who understand binary and those who don't" | Werkbak specs


  • TimMer
  • Registratie: Februari 2000
  • Niet online
In welk programma is dat? MySQL ondersteunt namelijk geen subselects.

  • Denhomer
  • Registratie: Augustus 2000
  • Laatst online: 12-10-2025

Denhomer

Doh !

Programma maakt al niet zoveel omdat hij zegt dat de query met 1 subselect ook werkt

Maar euh, je selecteerd niets van maxpostings, why need it then ?

  • ^Mo^
  • Registratie: Januari 2001
  • Laatst online: 04-11-2025
TimMer schreef op 12 september 2002 @ 00:47:
In welk programma is dat? MySQL ondersteunt namelijk geen subselects.
Sorry, was ik vergeten... het gaat in dit geval om MS Access. Het werkt inderdaad met één subquery wel (dus bv. alleen MinPostings), misschien kan access het wel niet met twee :? Lijkt me eigenlijk wel sterk maarja..
Maak ik nou gewoon een denkfout, of werkt het gewoon niet zoals ik zou denken?
Denhomer schreef op 12 september 2002 @ 00:47:
Programma maakt al niet zoveel omdat hij zegt dat de query met 1 subselect ook werkt

Maar euh, je selecteerd niets van maxpostings, why need it then ?
De MaxPostings is inderdaad op dit moment niet in gebruik, ben bezig de totale query stap voor stap op te bouwen... dus het is eigenlijk nog niet (helemaal) af om mijn beoogde doel te bereiken, maar als dit zou werken dan is er eigenlijk niet veel meer...

"There are 10 kinds of people in the world, those who understand binary and those who don't" | Werkbak specs


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
_Mo_: Zodra ik het MaxPostings gedeelte erbij pak, krijg ik alles 10 keer terug, dus in totaal 100 resultaten. Ik heb eigenlijk geen idee hoe het komt...
De betekenis van een SQL query met het volgende patroon:

code:
1
SELECT select-item* FROM table-ref* WHERE conditional-expression


is het volgende:

1) cartesisch product (CROSS JOIN) over de table-references.
2) selecteer uit dit cartesisch product de rijen die voldoen aan de conditionele expressie
3) projecteer de relatie door alleen de benodigde select-items over te laten.

Het klopt dus allemaal prima :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


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

Annie

amateur megalomaan

Heel simpel: je krijgt een cartesian product terug.

Je doet namelijk:
SELECT * FROM tableA, tableB

Vraagje: waarom gebruik je geen UNION of 2 WHERE IN statements?

edit: damn you, mbravenboer ;)

Today's subliminal thought is:


  • ^Mo^
  • Registratie: Januari 2001
  • Laatst online: 04-11-2025
Annie schreef op 12 september 2002 @ 00:54:
Heel simpel: je krijgt een cartesian product terug.

Je doet namelijk:
SELECT * FROM tableA, tableB

Vraagje: waarom gebruik je geen UNION of 2 WHERE IN statements?
Ben daar niet goed bekend mee, maar ik zal m'n boek daar nog eens goed op na slaan dan. * ^Mo^ moet terug naar de (sql) schoolbanken :/

"There are 10 kinds of people in the world, those who understand binary and those who don't" | Werkbak specs


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
_Mo_: /me moet terug naar de (sql) schoolbanken :/
Dat zou ik zeker maar eens doen als je niet weet wat cartesische producten zijn ;) . Ze vormen een belangrijk (maar eenvoudig) onderdeel van de relationele algebra en dus ook van SQL. Als je hiermee bekend bent, begrijp je pas echt wat queries nu eigenlijk betekenen....
Annie: damn you, mbravenboer ;)
:*)

Je zou een topic moeten kunnen locken als je aan het replien bent ;) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

mbravenboer schreef op 12 september 2002 @ 01:07:
:*)

Je zou een topic moeten kunnen locken als je aan het replien bent ;) .

Ik durf te wedden, dat (bijna) elke keer dat ik dat zou doen er een LA topic verschijnt ;)

  • ^Mo^
  • Registratie: Januari 2001
  • Laatst online: 04-11-2025
mbravenboer schreef op 12 september 2002 @ 01:07:
[...]

Dat zou ik zeker maar eens doen als je niet weet wat cartesische producten zijn ;) . Ze vormen een belangrijk (maar eenvoudig) onderdeel van de relationele algebra en dus ook van SQL. Als je hiermee bekend bent, begrijp je pas echt wat queries nu eigenlijk betekenen....
Ik heb het wel ooit gehad... heb alleen te lang niet echt SQL gedaan, behalve de standaard select/insert/etc. queries, maar geen joins/subqueries/etc.
Ik heb het inmiddels opgelost, nu ik wist wat er gebeurde ben ik met de volgende query gekomen:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
SELECT
    MinPostings.ID,
    MinPostings.Topic,
    MinPostings.UserID AS FirstPosterID,
    (
        SELECT
            Username
        FROM
            User
        WHERE
            ID = MinPostings.UserID
    ) AS FirstPosterName,
    (
        SELECT
            Username
        FROM
            User
        WHERE
            ID = MaxPostings.UserID
    ) AS LastPosterName,
    MaxPostings.Posted,
    (
        SELECT
            COUNT(MSG.ID)
        FROM
            Messages AS MSG
        WHERE
            MSG.ParentID = MaxPostings.ParentID
            AND
            MaxPostings.ParentID <> -1
    ) AS Replies,
    MinPostings.Locked
    FROM
        (
            SELECT
                *
            FROM
                Messages
            WHERE
                ID IN
                (
                    SELECT
                        MIN(ID)
                    FROM
                        Messages
                    GROUP BY
                        Topic
                )
        ) AS MinPostings,
        (
            SELECT
                *
            FROM
                Messages
            WHERE
                ID IN
                (
                    SELECT
                        MAX(ID)
                    FROM
                        Messages
                    GROUP BY
                        Topic
                )
        ) AS MaxPostings
    WHERE
        MinPostings.ID = MaxPostings.ParentID
        OR
        MinPostings.ID = MaxPostings.ID
    ORDER BY
        MinPostings.Locked,
        MaxPostings.Posted
        DESC

Ik denk echter dat efficiëntie vrij ver te zoeken is... :/ Maar ben niet bekend genoeg met SQL om het beter te doen, met joins bijvoorbeeld...

"There are 10 kinds of people in the world, those who understand binary and those who don't" | Werkbak specs


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Definieer het eens in 2 losse queries, als het eigenlijk twee losse queries zijn en stop ze dan samen met een UNION...

Eventueel ala:
select ... from (select .... UNION select ...) order by ....

Maar ik vraag me eigenlijk een beetje af wat je nou precies wilt?
Als ik een snelle blik op je query werp kan je volgens mij simpelweg je query ZONDER al die subselects doen (hooguit een enkele).

  • ^Mo^
  • Registratie: Januari 2001
  • Laatst online: 04-11-2025
ACM schreef op 12 september 2002 @ 02:38:
Definieer het eens in 2 losse queries, als het eigenlijk twee losse queries zijn en stop ze dan samen met een UNION...

Eventueel ala:
select ... from (select .... UNION select ...) order by ....

Maar ik vraag me eigenlijk een beetje af wat je nou precies wilt?
Als ik een snelle blik op je query werp kan je volgens mij simpelweg je query ZONDER al die subselects doen (hooguit een enkele).
Mijn tabel ziet er als volgt uit:
Messages
code:
1
  ID  |  UserID  |  Topic  |  Message  |  Posted  |  Locked  |  ParentID

Nu wil ik uit deze tabel een aantal verschillende dingen laten zien:
Topic, Locked -- deze kunnen uit de Parent komen of uit een van de replies, dat maakt niet echt uit.
Dan uit de MinPostings, dat is dus de Parent - het eerste bericht, wil ik het ID en het UserID (met de username, welke uit de User tabel komt).
Uit de MaxPostings, de laatste reply, wil ik Posted (de datum), het aantal replies (dus count(*) op alles met ParentID = x, waar x het huidige ID is) en de Username, welke ik met de UserID van de MaxPostings ophaal.

Wat ik van een UNION begrijp is dat deze de eerste query op een of andere manier aanvult, dus voor elk topic zou ik dan twee results krijgen, een setje uit de MinPostings, en een setje uit de MaxPostings (indien van toepassing).

"There are 10 kinds of people in the world, those who understand binary and those who don't" | Werkbak specs

Pagina: 1