Avatar billede oasen Nybegynder
28. maj 2003 - 22:00 Der er 37 kommentarer og
2 løsninger

En SQL-haj der kan hjælpe med et statement?

Jeg har opbygget et stort forum. Ved visning af alle spørgsmål joines fire tabeller, men jeg kan godt illustrere problemet med kun de to primære tabeller her - nemlig den med spørgsmål og den med svar.

Select spm.Overskrift, Count(svar.SvarID) As Indlaeg From spm Left Join svar On spm.SpmID = svar.SpmID Group By spm.Overskrift

Denne udtrækker alle spørgsmåloverskrifter fra tabellen "spm" og finder ud af, hvor mange relaterede poster, der findes i tabellen "svar" (altså antal indlæg i hvert spørgsmål).
Men nu kunne jeg godt tænke mig, at brugeren kunne vælge kun at få vist de spørgsmål, som vedkommende deltager i (dvs. fx. hvor svar.BrugerID=7).
Det er heller ikke noget problem med en where-clause, men så returnerer count (indlaeg) kun det antal poster som brugeren har lavet i den pågældende tråd logisk nok. Og den skal returnere ALLE. Præcis ligesom her på Eksperten under "Spørgsmål hvor du deltager".

Jeg giver 150 points for et brugbart svar!
Avatar billede arne_v Ekspert
28. maj 2003 - 22:23 #1
Har du prøvet med:

having svar.BrugerID=7

(istedetfor where svar.BrugerID=7)

?
Avatar billede bearhugx Nybegynder
28. maj 2003 - 22:24 #2
SELECT spm.Overskrift, count(svar.svarID) as Indlaeg
FROM spm, svar
WHERE (svar.BrugerID=7) AND (spm.SpmId=svar.SpmId)
GROUP BY spm.overskift
Avatar billede oasen Nybegynder
28. maj 2003 - 22:29 #3
2 sek...
Avatar billede bearhugx Nybegynder
28. maj 2003 - 22:30 #4
1....2.... :-)
Avatar billede bearhugx Nybegynder
28. maj 2003 - 22:36 #5
hmmm... efter at have læst dit indlæg (igen) tror jeg nok, at min løsning kommer frem til det samme, som dit forsøg - nemlig at den kun optæller de svar, som brugeren selv er ansvarlig for...

faktisk tror jeg ikke at du kan hente de (egenlig to forskellige) informationer ud med kun éen query ---
Avatar billede bearhugx Nybegynder
28. maj 2003 - 22:37 #6
måske kan du lave det med en subselect- men så skal du min køre MySQL 4.1 (nyeste release) og den er ikke "produktionsstabil" endnu...
Avatar billede oasen Nybegynder
28. maj 2003 - 22:38 #7
Hehe...
Jeg kan ikke få det til at fungere med Having. Der får jeg bare en fejlmeddelelse.
Jeg kan desværre ikke bruge din, bearhugx, fordi jeg har nogle left joins med de to øvrige tabeller, hvor jeg tjekker på null.
Avatar billede bearhugx Nybegynder
28. maj 2003 - 22:39 #8
mit umiddelbare gæt - lav 2 queries
Avatar billede oasen Nybegynder
28. maj 2003 - 22:39 #9
bearhugx -> Ja, de subselects har jeg savnet mange gange, da jeg er vant til dem fra Access/MS SQL.
Avatar billede oasen Nybegynder
28. maj 2003 - 22:42 #10
2 queries - hvor den ene kun udtrækker antal indlæg? Det kan vel også blive et problem, eftersom jeg også skal have en where-clause på den, for kun at tælle indlæg for de spørgsmål, hvor brugeren deltager.
Avatar billede bearhugx Nybegynder
28. maj 2003 - 22:44 #11
Jeg kan sige at jeg kører MySQL 4.1 nu - og selve db'en virker fint - men skal man til at bruge gui-interfaces såsom MysqlCC eller Mysql-front, så kan man kun logge på med root på Localhost (== Password=""), da der åbenbart er kommet et ny authentication scheme, som disse gui's ikke understøtter...
Avatar billede oasen Nybegynder
28. maj 2003 - 22:44 #12
Hvis det VIRKELIG ikke kan lade sig gøre, kan jeg kun se IN-operatoren som en løsning eller oprettelse af en fysisk temp-tabel. Men begge dele går temmelig meget ud over performance desværre...
Avatar billede bearhugx Nybegynder
28. maj 2003 - 22:45 #13
først lav en query, som finder alle spm, som bruger deltager i - derefter så query for count - for der har du jo allerede en liste med spmID - så det er forholdsvist nemt at lave det med 2 queries...
Avatar billede oasen Nybegynder
28. maj 2003 - 22:46 #14
Hvilken version af MySQL er den tidligste, der understøtter sub-selects (og for alt i verden også gerne fremmednøgler!) ?
Avatar billede oasen Nybegynder
28. maj 2003 - 22:48 #15
Altså:

Select spmID From svar Where BrugerID = 7

Og så samle op i en kommasepareret liste.
Og til sidst udtrække alle data:

Select spm.Overskrift, Count(svar.SvarID) As Indlaeg From spm Left Join svar On spm.SpmID = svar.SpmID Where spm.SpmID IN(liste) Group By spm.Overskrift

?
Avatar billede bearhugx Nybegynder
28. maj 2003 - 22:49 #16
Det er et lidt problematisk spm, da MySQL AB har en del, som de gerne vil have med i deres 4.1 -

4.1.0 er i alpha-release og der virker subselects pt. - men som sagt - det er kun alpha --- Så det eneste, jeg kan sige er at subselect-mulighed er kommet ind under udarbejdelsen af 4.1.0 - men hvornår ...????
Avatar billede arne_v Ekspert
28. maj 2003 - 22:54 #17
Ja noget i den stil.

Hvis den liste kan blive meget lang, så er det muligt at det var
bedre at hive de spmID over i en temporær tabel og joine med den.
Avatar billede oasen Nybegynder
28. maj 2003 - 22:56 #18
Listen vil ikke indeholde mere end 20 ID'er pr. gang, da det er paging-størrelsen. Der skal lige tilføjes en Limit bag på den i så fald.

Hvad er det forskellen er på Max-versionen og den almindelige?
Avatar billede oasen Nybegynder
28. maj 2003 - 22:58 #19
Hvorfor tror du i øvrigt den gav fejl ved Arne_V's svar?
Avatar billede bearhugx Nybegynder
28. maj 2003 - 22:58 #20
hvis du arbejder i PHP vil jeg gøre det således (IKKE TESTET)

$querySpm = "SELECT spm.Overskrift, spm.SpmId FROM spm, svar WHERE (svar.BrugerID=7) AND (spm.SpmId=svar.SpmId) GROUP BY spm.overskift";
$resultSpm = mysql_query( $querySpm );
for(i=0;i<mysql_num_rows($resultSpm);++i) {
  $spm = mysql_fetch_object( $resultSpm );
  $queryCount = "SELECT count(svar.SvarId) as Indlaeg FROM svar WHERE svar.SpmId =".$spm->SpmId;
  $resultCount = mysql_query( $queryCount );
  if(mysql_num_rows($resultCount) > 0 ) {
    $count = mysql_fetch_object( $resultCount );
    $indlaeg = $count->Indlaeg;
  } else {
    $indlaeg = 0;
  }
  print(" Spørgsmålet ".$spm->Overskift." har ".$indlaeg." indlæg ");
}
Avatar billede arne_v Ekspert
28. maj 2003 - 23:00 #21
MAX versionen er versionen med InnoDB tabeller (med transactions).
Avatar billede oasen Nybegynder
28. maj 2003 - 23:00 #22
Nej, det er ASP - men jeg tror, jeg kan se idéen...
Avatar billede oasen Nybegynder
28. maj 2003 - 23:01 #23
Jeg satte også 3.23 op til Inno-tabeller, men kunne ikke få fremmednøglerne til at fungere.
Avatar billede arne_v Ekspert
28. maj 2003 - 23:01 #24
Min having virkede ikke, fordi man kun kan bruge having på
noget der rent faktisk selectes.

Det havde jeg glemt.

Du kan derfor kun bruge having til:

Select spm.Overskrift, Count(svar.SvarID) As Indlaeg From spm Left Join svar On spm.SpmID = svar.SpmID Group By spm.Overskrift having spm.overskrift like 'a%'

(fordi spm.overskrift faktisk bliver selected)
Avatar billede oasen Nybegynder
28. maj 2003 - 23:05 #25
Hvis jeg også vælger svar.SvarID, får jeg ikke en fejlmeddelelse mere. Men resultatet er det samme som med Where.
Avatar billede oasen Nybegynder
28. maj 2003 - 23:06 #26
Undskyld: svar.BrugerID...
Avatar billede oasen Nybegynder
28. maj 2003 - 23:09 #27
Der står da ellers her, at standard-4.0 har Inno-tabeller?
http://www.mysql.com/downloads/mysql-4.0.html
Avatar billede arne_v Ekspert
28. maj 2003 - 23:10 #28
Udover at selecte svar.brugerID har du også måttet tilføje den til
group by, fordi alle ikke aggregerede funktioner i select listen
også skal optræde i group by.

Og det er det som er skyld i at igen bliver der sorteret for meget
fra.
Avatar billede oasen Nybegynder
28. maj 2003 - 23:11 #29
Ja, suk...

Eksperten må jo gøre noget alá det samme, eftersom de også benytter MySQL!?
Avatar billede oasen Nybegynder
28. maj 2003 - 23:15 #30
Er det i så fald værd at prøve 4-serien?
Og hvilken er mest stabil/gennemtestet, hvis den skal have Inno-tabeller og fremmednøgler?
Avatar billede arne_v Ekspert
28. maj 2003 - 23:18 #31
Du kan selv læse midt på:
  http://www.mysql.com/downloads/mysql-3.23.html
at MAX=InnoDB.

I 4.0 er InnoDB med i standard men MAX indeholder såsom BDB (se
midt på det link du selv angav).
Avatar billede arne_v Ekspert
28. maj 2003 - 23:19 #32
4.0 er recommended idag.

Jeg turde nok ikke prøve 4.1 (men jeg er en forsigtig person).
Avatar billede oasen Nybegynder
28. maj 2003 - 23:25 #33
Og så lige for de tungnemme:

MAX = InnoDB = Fremmednøgler/Subselects (fra 4.0) ?
Avatar billede oasen Nybegynder
28. maj 2003 - 23:29 #34
Der står ikke noget nævnt om MAX til Windows. Der er kun én version i modsætning til Linux...
Avatar billede arne_v Ekspert
28. maj 2003 - 23:42 #35
3.x standard : ikke InnoDB
3.x MAX : InnoDB

4.x standard : InnoDB (4.x MAX har så nogle andre goodies)

InnoDB tables har transactions (normal MyISAM har ikke).

Der er kommet flere SQL features med i 4.0 og vil komme endnu
flere med i 4.1 (jeg kan ikke huske listen).

Jeg mener ikke at InnoDB versus MyISAM har noget med SQL features
at gøre. Forskellen ligger i transaktioner eller ej.

4.0 Windows indeholde både standard og MAX executables står der
på download siden:


Windows downloads
The Windows download contains both the Standard and Max server binaries
Avatar billede oasen Nybegynder
28. maj 2003 - 23:45 #36
Mange tak - jeg vender lige tilbage i morgen, når jeg har tygget lidt på svarene...
Avatar billede oasen Nybegynder
02. juni 2003 - 15:57 #37
Jeg må nok bare bruge IN-operatoren. Men jeg siger mange tak for hjælpen!

Vil I lægge et par svar?
Avatar billede arne_v Ekspert
02. juni 2003 - 17:36 #38
svar
Avatar billede bearhugx Nybegynder
03. juni 2003 - 00:50 #39
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