Avatar billede -lps- Nybegynder
04. november 2009 - 15:38 Der er 9 kommentarer

Gentagelse af statement med subqueries

Hejsa.

Jeg har et lille problem jeg håber nogen kan hjælpe mig med. Her er et meget forenklet eksempel:

Jeg har 2 tabeller, hvorfra jeg skal bruge informationer.
Tabel1 indeholder bl.a. id, dato, tilstand og tabel2_Id
Tabel2 indeholder bl.a. id og gruppe

Eks:

Tabel1
Id    dato    tilstand    tabel2_Id
1    2009:10:01    A    1
2    2009:10:04    B    1
3    2009:10:06    A    1
4    2009:10:02    A    2
5    2009:10:10    C    1
6    2009:10:24    A    1
7    2009:10:35    B    2
8    2009:10:12    C    2

Tabel2
Id    gruppe   
1    Gruppe1
2    Gruppe2


Jeg har brug for at vide hvor mange rækker i tabel 1, der er i hver tilstand, for hver gruppe i en given periode. 
Det jeg har indtil videre er:

SELECT (SELECT COUNT(tabel1.id)
FROM tabel1 JOIN tabel2 ON tabel2.id=tabel1. Tabel2_Id
    WHERE dato >= 'xxxx-xx-xx' AND dato < 'XXXX:XX:XX' AND tabel2.gruppe= Gruppe1)
    AS 'I Alt',
(SELECT COUNT(tabel1.id)
    FROM Tabel1 JOIN tabel2 ON tabel2.id=tabel1. Tabel2_Id
WHERE tilstand=1 AND dato >= 'xxxx-xx-xx' AND dato < 'XXXX:XX:XX' AND tabel2.gruppe= Gruppe1)
    AS 'Tilstand A',
(SELECT COUNT(tabel1.id)
    FROM Tabel1 JOIN tabel2 ON tabel2.id=tabel1. Tabel2_Id
WHERE tilstand=2 AND dato >= 'xxxx-xx-xx' AND dato < 'XXXX:XX:XX' AND tabel2.gruppe= Gruppe1)
    AS 'Tilstand B',
(SELECT COUNT(tabel1.id)
    FROM Tabel1 JOIN tabel2 ON tabel2.id=tabel1. Tabel2_Id
WHERE tilstand=3 AND dato >= 'xxxx-xx-xx' AND dato < 'XXXX:XX:XX' AND tabel2.gruppe= Gruppe1)
    AS 'Tilstand C';

Dette giver mig de ønskede informationer for den gruppe jeg har specificeret i WHERE-betingelserne, men jeg ønsker i stedet at få en liste indeholdende disse informationer for hver gruppe i tabellen, på hver sin række (som flg.)

Gruppe    I Alt    Tilstand A     Tilstand B    Tilstand C
Gruppe1    5    3    1    1       
Gruppe2    3    1    1    1

På forhånd tak :-)
Avatar billede Slettet bruger
04. november 2009 - 16:14 #1
Prøv denne (ikke testet):
SELECT
    COUNT(*) as `count`,
    `tabel1`.`tilstand`,
    `tabel2`.`gruppe`
FROM
    `tabel1` INNER JOIN `tabel2` ON (
        `tabel1`.`tabel2_id` = `tabel2` .`id` AND
        `tabel1`.`dato` >= 'xxxx-xx-xx' AND
        `tabel1`.`dato` < 'XXXX:XX:XX'
    )
GROUP BY
    `tabel2`.`gruppe`,
    `tabel1`.`tilstand` WITH ROLLUP

Den skulle outputte noget i retning af:

count    tilstand    gruppe
3    A        Gruppe1
1    B        Gruppe1
1    C        Gruppe1
4    NULL        Gruppe1
1    A        Gruppe2
1    B        Gruppe2
1    C        Gruppe2
3    NULL        Gruppe2
Avatar billede -lps- Nybegynder
04. november 2009 - 17:06 #2
Tak for dit forslag, men det jeg har brug for er jo et output, der ser ud som flg (Fik ikke lige kolonnerne til at stå helt rigtigt i oplægget):

Gruppe    I Alt    Tilstand A    Tilstand B    Tilstand C
Gruppe1    5              3                  1                  1     
Gruppe2    3              1                  1                  1

Er det muligt at få det "vendt om" på den måde?
Avatar billede Slettet bruger
04. november 2009 - 19:29 #3
Jeg foreslår du bruger mit forslag og efterfølgende formaterer der i et andet sprog - SQL er ikke optimalt til at tilføje ekstra kolonner på den måde.

Jeg går ud fra, du har et præsentationslag, der kan udføre din formateringslogik?
Avatar billede -lps- Nybegynder
05. november 2009 - 10:40 #4
Jeg er godt klar over at SQL ikke er det optimale til netop det udtræk jeg har brug for her, men jeg ved det er muligt at få det ønskede udtræk. Jeg har faktisk allerede en løsning, men da den indeholder en del temporary tables er den ALT for langsom at køre. Derfor håbede jeg på hjælp til at finde en bedre løsning, som stadig kun omfatter SQL.
Avatar billede Slettet bruger
05. november 2009 - 12:20 #5
Er der kun 2 grupper?
Er der kun 3 tilstande?

Ville det ikke være en bedre ide at optimere på hele udtrykket? Jeg tror ikke, der er noget vundet ved at transponere tilstandende.
Avatar billede -lps- Nybegynder
05. november 2009 - 13:46 #6
Der er (foreløbigt) 8 tilstande og et ukendt antal grupper. Eksemplet ovenfor er meget forenklet. De faktiske tabeller indeholder flere tusinde rækker hver(i tabel2 optræder hver gruppe flere grundet afvigelser i de resterende informationer.
Der kan ikke ændres på hvilket format output skal have, da de nævnte data kun er et uddrag af det faktiske udtræk.
Grundet tabellernes størrelse er det heller ikke muligt at optimere min løsning med temporary tables nok til at den er brugbar (laveste execution tid jeg har opnået er stadig over 1 minut).

Jeg prøver at lade spørgsmålet stå for at se om der er nogen, der har en løsning, men alternativt må jeg bruge mit udgangspunkt fra oplægget og så kode mig ud af gentagelses problematikken et eller andet sted.
Avatar billede Slettet bruger
05. november 2009 - 14:29 #7
Jeg vil stadig stærkt anbefale dig en anden løsning.

Har du indexeret dine tabeller?
Har du fået nogle andre til at se på din totale query? Prøv at poste her - så kan jeg tage et kik på den og se, om der er optimeringsmuligheder.
Avatar billede -lps- Nybegynder
05. november 2009 - 15:22 #8
Jeg har haft en anden til at kigge på optimeringen uden held.
Tak for tilbuddet om at kigge på det, men det vil det være for omfattende at forklare alle de nødvendige relationer mm.
Avatar billede Slettet bruger
05. november 2009 - 15:36 #9
Hvis du har en query der virker kan jeg jo bare aflure derfra. Men det er self. op til dig.

Men vigtigst af alt: har du indexeret? Det har ALT at sige, at grundlæggende indexes er på plads!
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





White paper
Rapport kortlægger de 13 bedste muligheder for at sætte turbo på din cloud computing