Avatar billede jansangill Nybegynder
11. august 2007 - 02:25 Der er 25 kommentarer og
1 løsning

lave et kald istedet for flere.

Jeg har bøvlet en del med SQL idag og har ikke kunne fine frem til en løsning på det.

Jeg har lige pt 3 kald, som jeg gerne vil formindske til et kald, eller 2.

Disse kald ville ikke hjælpe på performance, og et af dem er lige pt med i et do while not loop, hvorved den liver kaldt ved hver ny nyhed der loopes ud.

Håber i kan hjælpe mig, da jeg ikke helt kan overskue hvordan disse 3 skal joines sammen så det virker.

jan


Set RS = Server.CreateObject("ADODB.Recordset")
SQL = "SELECT * from vurdering_rejsemael where status = 2 AND dest_id="&nn("id")
RS.Open SQL, Conn, 1, 3

sql = "select count(*) as antal from vurdering_rejsemael where status = 2 AND dest_id="&rs("id")
SET RS3 = Conn.Execute(sql)

sql1 = "select count(*) as antal1 from vurdering_rejsemael where status = 2 AND dest_id="&nn("id")
SET RS4 = Conn.Execute(sql1)
Avatar billede arne_v Ekspert
11. august 2007 - 02:44 #1
Det er muligt at du kan løse opgaven med brug af noget GROUP BY, men det er ikke til
at sige med sikkerhed udfra de foreliggende oplysninger.
Avatar billede jansangill Nybegynder
11. august 2007 - 09:49 #2
Okay, en lidt længere forklaring:(har lavet nogle ændringer, da jeg ville have det hele i samme tabel.)


Set RS = Server.CreateObject("ADODB.Recordset")
SQL = "SELECT * from nyheder where parendtID = 2 AND dest_id="&nn("id")
RS.Open SQL2, Conn, 1, 3

sql = "select count(*) as antal from nyheder where parendtID = 2 AND dest_id="&rs("id")
SET RS3 = Conn.Execute(sql)

sql1 = "select count(*) as antal1 from nyheder where parendtID = 2 AND dest_id="&nn("id")
SET RS4 = Conn.Execute(sql1)



Jeg looper nogle nyheder ud på mainsiden. Disse nyheder skal kunne tælles på både mainsiden og undersiden (de enkelte nyheder).  Den første SQL bruges til at åbne databasen og sørger for at brugeren kan skrive kommentarer på diverse indlæg, hvor der er paging på.

Den anden sql bruges til at tælle antal kommentarer i hver enkelt nyhed på mainsiden. Lige pt er den i et loop, og den bliver kaldt hver gang der er en ny nyhed der loopes ud.Her bruger jeg id fra de nyheder der bliver loopet ud: rs("id").


Den tredje sql bruges til at tælle kommentar på undersiden, hvor status er 2 og id = den id der bliver sendt videre med linket( nn("id") ).


Håber det forklarede det lidt bedre. Ellers må du jo sige til:)
Avatar billede kjulius Novice
11. august 2007 - 19:45 #3
Tja, jeg må sige, at også jeg, selv efter den nye forklaring har problemer med at forstå det. Det ville hjælpe gevaldigt, hvis du kunne give et outline af din tabelstruktur og hvordan de forskellige felter (især id, parentID og dest_id) relaterer til hinanden.

Din hidtidige forklaring er lidt for indforstået og fordrer en viden om din applikation vi ikke har. Det er lidt sort snak... :-)
Avatar billede jansangill Nybegynder
11. august 2007 - 22:29 #4
okay har lavet en gif med tabelstrkturen, og prøvet at forklare det lidt der også. Håber det giver mere mening nu.

http://www.jansangill.dk/table.gif
Avatar billede -psycho- Nybegynder
11. august 2007 - 23:35 #5
ikke for noget men du burde ikke have kommentar og nyheder i samme tabel hvis der skal kunne være mere end 1 kommentar det er dårlig design imo.

Split det op i 2 tabler en med nyheder og en med kommentar og i kommentar har du så bare en ref til nyhedsid'et så du ved hvilken nyhed kommentaren høre til.
Avatar billede jansangill Nybegynder
12. august 2007 - 00:33 #6
Det havde jeg også i starten, ved ikke helt hvorfor jeg ændrede det. Ændrer det nok også tilbage snart.
Avatar billede kjulius Novice
12. august 2007 - 00:50 #7
Tak for overblikket. :-) Helt gennemskuet det har jeg nok ikke, men jeg skal alligevel prøve at lave en forespørgsel, som vil vise et resultat. Hvad siger du til denne her?

SELECT n1.*, COALESCE(COUNT(n2.id), 0) AS antalKommentarer
FROM nyheder n1
LEFT JOIN nyheder n2 ON n1.dest_id = n2.id and n2.parentid = 2
WHERE n1.parentid = 1
GROUP BY n1.id, n1.parentID, n1.overskrift, n1.korttekst, n1.langtekst, n1.image, n1.datostart, n1.datostart_tid, n1.datoslut, n1.online, n1.Skrevetaf, n1.navn, n1.email, n1.kommentar, n1.dest_id

Da du siger, at forespørgsel et skal bruges til at vise nyhederne på forsiden, forstår jeg ikke helt, at du så selekterer på parentid=2. Skulle det ikke have været 1 i stedet (iflg. dine tabelkommentarer)? Det er jeg gået ud fra.
Jeg kan ikke umiddelbart se forskel på din forespørgsel 2 og 3, bortset fra hvilken id  der vælges.
Det er sikkert min fejl, og jeg ser derfor frem til at blive korrekset. :-)
Avatar billede jansangill Nybegynder
12. august 2007 - 01:11 #8
ked af at sige det kjuæius, men har lige ændret min database struktur, som du også kan se på den nye table, samme link:http://www.jansangill.dk/table.gif.

I bund og grund er det samme id der vælges ud fra kjulius, måske er det mig der forvirer. Det jeg gør ved nn("id"), er bare at request("id") udfra denne link:<a href="<%=p1 & "/laesmere"%>&id=<%=rs("id")%>">.

Men ja jeg kunne liså godt bare gøre dette, som jeg dog også gør nu:

Set RS2 = Server.CreateObject("ADODB.Recordset")
SQL = "SELECT * from nyheder_kommentar where parentID ="&rs("id")
RS2.Open SQL, Conn, 1, 3

sql1 = "select count(*) as RSantal from nyheder_kommentar where parentID ="&rs("id")
SET RS1 = Conn.Execute(sql1)

sql3 = "select count(*) as antal1 from nyheder_kommentar where parentID="&rs("id")
SET RS3 = Conn.Execute(sql3)


Håber du har lyst til at komme med et nyt forslag, udfra den nye struktur, da den jo hæjst sansynligvis har ændret sig lidt.
Avatar billede jansangill Nybegynder
12. august 2007 - 01:14 #9
Grunden til at jeg har to forespørgsler lige pt er, at jeg ikke kan få vist antallet af kommentar på mainsiden hvor nyheder loopes ud, uden at sætte sql'en ind i loopet, og sørge for at den tæller hver count for hver id i loopen.
Avatar billede kjulius Novice
12. august 2007 - 02:00 #10
Okay, men ændrer det ret meget? Mit forslag ville så lyde:

SELECT n.*, COALESCE(COUNT(k.id), 0) AS antalKommentarer
FROM nyheder n
LEFT JOIN nyheder_kommentar k ON k.parentid = n.id
GROUP BY n.id, n.parentID, n.overskrift, n.Skrevetaf, n.korttekst, n.langtekst, n.image, n.datostart, n.datostart_tid, n.datoslut, n.online
Avatar billede kjulius Novice
12. august 2007 - 02:04 #11
Hvorfor har du forresten bibeholdt parentID feltet i din hovedtabel (nyheder)? Det felt har vel mistet sin funktion i den tabel, eller er der endnu et niveau over nyheder?
Avatar billede jansangill Nybegynder
12. august 2007 - 02:32 #12
hehe ja, parentID i nyheder er der så jeg kan styre andre ting, som ikke har med dette at gøre:)
Avatar billede jansangill Nybegynder
12. august 2007 - 02:42 #13
får denne fejl ved forsøget:

Microsoft OLE DB Provider for ODBC Drivers error '80040e14'

[Microsoft][ODBC SQL Server Driver][SQL Server]The text, ntext, and image data types cannot be compared or sorted, except when using IS NULL or LIKE operator.
Avatar billede kjulius Novice
12. august 2007 - 02:52 #14
Hmmm.. Så kan man åbenbart ikke putte et image-type felt i en GROUP BY. Det besværliggør det jo lidt hvis det felt også skal med. Prøv med:

SELECT n.*, AntalKommentarer
FROM nyheder n
INNER JOIN (
SELECT n.Id, COALESCE(COUNT(k.id), 0) AS AntalKommentarer
FROM nyheder n
LEFT JOIN nyheder_kommentar k ON k.parentid = n.id
GROUP BY n.id) x
ON x.id = n.id
Avatar billede jansangill Nybegynder
12. august 2007 - 11:06 #15
Denne SQL gør således at den tæller alle post sammen, og skriver den samme antal kommentar på hver nyhed.
Avatar billede -psycho- Nybegynder
12. august 2007 - 11:14 #16
SELECT *, (SELECT COUNT(*) FROM nyheder_kommentar WHERE nyheder_kommentar.parentID = nyheder.id) AS AntalKommentarer FROM nyheder
Avatar billede jansangill Nybegynder
12. august 2007 - 11:26 #17
desærre. Dette tæller også alle comments og skriver samme antal på hver comment:(
Avatar billede jansangill Nybegynder
12. august 2007 - 11:29 #18
nej jeg tar fejl, det tæller kun den første record, og displayer den i alle.
Avatar billede kjulius Novice
12. august 2007 - 15:04 #19
Du skriver: "Denne SQL gør således at den tæller alle post sammen, og skriver den samme antal kommentar på hver nyhed."

Det håber jeg da bestemt ikke. Meningen var at det skal vise alle NYHEDER og angive hvor  mange kommentarer der er til HVER ENKELT nyhed.

Hvis den skriver samme antal kommentarer ved alle NYHEDER, så... - ku' jeg bede dig tjekke, om dine data i så fald stemmer overens med dine forventninger, altså om dine data er korrekte? Og om du har tastet forespørgslen korrekt ind? Jeg kan nemlig ikke se nogen fejl i forespørgslen som skrevet i min post 02:52:00... :-(
Avatar billede jansangill Nybegynder
12. august 2007 - 15:13 #20
kjulius. Jeg kan ikke sige med 100% sikekrhed at jeg har udført det korrekt. Men ja, den tæller alle n´kommentar til nyhedrne korrekt nok, hvis man er inde på nyheden. Men hvis man ikke er inde på nyheden, så vises den første coutn kun. med det mener jeg, at den ikke tæller antal kommentar til anden nyhed.

Det jeg gør for at få antal kommenat på mainsiden, hvor alle nyhederne loopes ud er:

do while not x.eof

  antal = x("AntalKommentarer")

  response.write antal & " kommentarer" & "<br>"

  x.moveNext

loop
Avatar billede jansangill Nybegynder
12. august 2007 - 16:03 #21
okay kjulies nu virker det næsten efter hensigten.

Men jeg kan desværre ikke få den til at vise alle informationerne nu, der hvor nyherne loopes ud.

Den vil godt vise alle informationer omkring alle andre end den første nyhed.

Her er en billede, hvorved du kan se det:

http://www.jansangill.dk/billede.gif.

Dette sker ligemeget hvilken rækkefælge den er i. Dvs at der er informationer i alle felter, den vil bare ikke udskrive dem alle i den første, kun nogle af dem?

jan
Avatar billede kjulius Novice
12. august 2007 - 16:25 #22
Jeg tvivler på, at det er i SQL koden problemet ligger, det er nok snarere i ASP scriptet.
Avatar billede jansangill Nybegynder
12. august 2007 - 17:35 #23
er fuldstændig enig. Kunne godt være du havde været ude for det fær dog, og lige have svaret. Men jeg fandt ud af det efter et stykke tid.

Smider du et svar, og mange tak for hjælpen. Havde nok ikke selv kunne finde på den sql sætning lige pt.

Men hvis du måske kunne forklare den SQL stren, så jeg kunne få lidt indsigt i den:

SELECT n.*, AntalKommentarer
FROM nyheder n
INNER JOIN (
SELECT n.Id, COALESCE(COUNT(k.id), 0) AS AntalKommentarer
FROM nyheder n
LEFT JOIN nyheder_kommentar k ON k.parentid = n.id
GROUP BY n.id) x
ON x.id = n.id

Du selecter n.*?, og antalKommenatar?  Og hvad sørger dette for:COALESCE(COUNT(k.id), 0)
Avatar billede kjulius Novice
12. august 2007 - 19:37 #24
Okay, jeg skal forsøge... :-)

Yderst er der følgende forespørgsel:

SELECT n.*, AntalKommentarer
FROM nyheder n
INNER JOIN x ON x.id = n.id

Det interessante er her, at du jo ikke har defineret en tabel ved navn x. Det er en midletidig tabel, som er opstået ved at udføre den inderste forespørgsel:

SELECT n.Id, COALESCE(COUNT(k.id), 0) AS AntalKommentarer
FROM nyheder n
LEFT JOIN nyheder_kommentar k ON k.parentid = n.id
GROUP BY n.id

Denne midlertidige tabel opstår ved at omkranse en forespørgsel i paranteser og efterfølgende navngive den (betegnelsen umiddelbart efter den afsluttende parantes. Når en sådan forespørgsel i parantes først er navngivet kan den efterfølgende bruges som enhver enden tabel.

I den midlertidige tabel er det mest interessante tælleren. COUNT(k.id) tæller antallet at forekomster af feltet id i tabellen nyheder_kommentar. Ved at angive et felt(altså COUNT(k.id), i stedet for COUNT(*) vil kun felter som ikke er null blive talt. Da tabellen er refereret med en LEFT JOIN kan det forekomme, at der ikke er oprettet kommentarer, og der derfor bliver returneret en null værdi. Disse bliver ikke talt med, men hvis der overhovedet ikke er nogen rækker, der opfylder kriteriet vil COUNT ikke returnere tallet 0, men derimod null (ingenting). Det er her COALESCE funktionen tager over. Med den funktion kan man angive, at null skal erstattes af en anden værdi. Da det i dette tilfælde er angivet til 0, er resultatet at der alligevel vil blive returneret tallet 0 i stedet for null (ingenting).

Jeg håber det giver mening... :-)
Avatar billede kjulius Novice
12. august 2007 - 19:49 #25
I den yderste forespørgsel betyder

SELECT n.*, AntalKommentarer

at den skal returnere alle felter fra tabellen nyheder (som er blevet givet et alias på n) og feltet AntalKommentarer fra den midlertidige (eller virtuellle, om du vil) tabel ved navn x. Da feltet kun optræder i x er det ikke nødvendigt at kvalificere det med x.AntalKommentare, selv om man selvfølgelig kan gøre det for klart at angive hvor feltet kommer fra.
Avatar billede jansangill Nybegynder
12. august 2007 - 20:01 #26
tak for hjælpen. Det gav lidt mere mening nu:)
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