18. december 2007 - 23:06Der er
37 kommentarer og 1 løsning
sql,count
Halloi, håbede der var en eller 2 som måske kuinne hjælpe mig med at flette en count ind i min sql. Meningen er at jeg vil left joine en count ind i min sql for at tælle antal forkomster af g_id i tabellen kat_vare_placering, men det lykkedes bare slet ikke for mig. Får hele tiden forskelliege fejl, såsom denne her:
The multi-part identifier "a.id" could not be bound.
Her er sql'en:
SELECT *, a.id as gID, a.parent_id FROM kat_varegrp a, kat_varegrp_indh b
LEFT JOIN(SELECT COUNT(g_id) AS antalKommentarer FROM kat_vare_placering c ON a.id=c.g_id)
WHERE a.id = b.grp_id AND a.butik_id = "&butikID&" AND b.sprog_id = "&sprogid&" AND b.online = 1 ORDER BY a.parent_id, a.rakkefolge ASC"
Skal siges at sql'en virker fint uden jeg prøver at left joine en count ind, men har desværre brug for at vide antal af forekomster:(
Umiddelbart ville jeg forvente at du skulle joine kat_varegrip, kat_varegrp_indh og kat_vare_placering og så optælle kat_vare_placering.*, samt gruppere på de resterende felter.
Jeg kan ikke lige gennemskue hvorfor du vil tildele alias til a.id og hvorfor a.parent_id skal vælges 2 gange (en gang via * og en gang ved specifik angivlse af kolonnen a.parent_id)?
Mit umiddelbare bud ville være noget i stil med:
SELECT a.id, a.parent_id, a.butik_id, a.rakkefolge b.id, b.sprog_id, b.online, COUNT(c.*) as antalKommentarer FROM kat_varegrp AS a INNER JOIN kat_varegrp_indh AS b ON b.grp_id = a.id LEFT JOIN kat_vare_placering AS c ON c.g_id = a.id WHERE a.butik = @butikID AND b.sprog_id = @sprogID AND b.online = 1 GROUP BY a.id, a.parent_id, a.butik_id, a.rakkefolge b.id, b.sprog_id, b.online ORDER BY a.parent_id, a.rakkefolge
SELECT a.id as gID,a.parent_id,a.rakkefolge,b.navn,b.url,b.beskrivelse,b.grp_id, COUNT(c.*) as antalKommentarer FROM kat_varegrp AS a INNER JOIN kat_varegrp_indh AS b ON b.grp_id = a.id LEFT JOIN kat_vare_placering AS c ON c.g_id = a.id WHERE a.butik = "&butikID&" AND b.sprog_id = "&sprogid&" AND b.online = 1 GROUP BY a.id ,a.parent_id,a.rakkefolge,b.navn,b.url,b.beskrivelse,b.grp_id ORDER BY a.parent_id, a.rakkefolge
Ups! Der mangler lige et komma efter a.rakkefolge i select-listen og i group by-listen. Desuden skrev jeg a.butik i stedet for a.butik_id i where-delen.
SELECT a.id, a.parent_id, a.butik_id, a.rakkefolge, b.id, b.sprog_id, b.online, COUNT(c.*) as antalKommentarer FROM kat_varegrp AS a INNER JOIN kat_varegrp_indh AS b ON b.grp_id = a.id LEFT JOIN kat_vare_placering AS c ON c.g_id = a.id WHERE a.butik_id = @butikID AND b.sprog_id = @sprogID AND b.online = 1 GROUP BY a.id, a.parent_id, a.butik_id, a.rakkefolge, b.id, b.sprog_id, b.online ORDER BY a.parent_id, a.rakkefolge
For lige at adressere den med optællingen, så tror jeg du skal lave en subquery som returnerer antal kommentarer i stedet og så fjerne LEFT JOIN helt:
SELECT a.id as gID,a.parent_id,a.rakkefolge, b.navn,b.url,b.beskrivelse,b.grp_id, (SELECT COUNT(*) FROM kat_vare_placering WHERE g_id = a.id) AS antalKommentarer FROM kat_varegrp AS a INNER JOIN kat_varegrp_indh AS b ON b.grp_id = a.id WHERE a.butik = "&butikID&" AND b.sprog_id = "&sprogid&" AND b.online = 1 GROUP BY a.id ,a.parent_id,a.rakkefolge,b.navn,b.url,b.beskrivelse,b.grp_id ORDER BY a.parent_id, a.rakkefolge
Du kan evt. lave hele den forrige query til en subquery og så vælge dine blob-felter i en query baseret på den du lige har fået til at fungere.
SELECT d.*, e.tekst, e.billede FROM ( SELECT a.id as gID,a.parent_id,a.rakkefolge, b.navn,b.url,b.beskrivelse,b.grp_id, (SELECT COUNT(*) FROM kat_vare_placering WHERE g_id = a.id) AS antalKommentarer FROM kat_varegrp AS a INNER JOIN kat_varegrp_indh AS b ON b.grp_id = a.id WHERE a.butik = "&butikID&" AND b.sprog_id = "&sprogid&" AND b.online = 1 GROUP BY a.id ,a.parent_id,a.rakkefolge,b.navn,b.url,b.beskrivelse,b.grp_id ) AS d INNER JOIN kat_varegrp_indh AS e ON e.id = d.gID ORDER BY d.parent_id, d.rakkefolge
Jeg vil stadig mene at du bare skal flytte beskrivelsen ud af subquery'en som jeg har illustreret i eksemplet 18/12-2007 23:52:42, altså sådan her:
SELECT d.*, e.beskrivelse, e.billede FROM ( SELECT a.id as gID, a.parent_id, a.rakkefolge, b.navn, b.url, b.grp_id, (SELECT COUNT(*) FROM kat_vare_placering WHERE g_id = a.id) AS antalKommentarer FROM kat_varegrp AS a INNER JOIN kat_varegrp_indh AS b ON b.grp_id = a.id WHERE a.butik = "&butikID&" AND b.sprog_id = "&sprogid&" AND b.online = 1 GROUP BY a.id, a.parent_id, a.rakkefolge, b.navn, b.url, b.grp_id ) AS d INNER JOIN kat_varegrp_indh AS e ON e.id = d.gID ORDER BY d.parent_id, d.rakkefolge
Spørg bare løs, så må vi se om jeg kan hjælpe... :-)
har denne sql, som har irreteret mig et lille stykke tid:
SELECT *, kv.id AS vareID FROM kat_vare kv JOIN kat_vare_indh kvi on (kvi.vare_id = kv.id) JOIN kat_vare_placering kvp on (kvp.v_id = kv.id) LEFT JOIN kat_billede kb ON (kb.vare_id = kv.id) WHERE (kvp.g_id = "&nn("kid")&") AND (kvi.sprog_id = "&sprogid&") AND (kvi.online = 1) ORDER BY kvp.rakkefolge ASC
Lige nu virker den næsten efter hensigten, men den optæller alt for mange records.
baggrundsinformation:
Jeg left joiner ind en tabel, som indeholder masser af billeder, som bliver gemt som alm nvchar.
a.id, som er "varen" kan have masse af billeder til samme id, uendelig faktisk.
Problemet lige nu ligger i at hvis i billede tabbelen der er 5 billeder til en vare, så bliver den skrevet ud 5 gange, som jeg finder mærkelig, da jeg left joiner den ind. Men det er der sikkert en forklaring på.
Det der skal ske er at den kun skriver varen ud 1 gang, og ikke 5 gange, hvis der er 5 billeder.
SELECT kvp.rakkefolge,kvi.navn,kvi.kort_beskr,kvp.g_id,kb.billede, kv.id AS vareID FROM kat_vare kv JOIN kat_vare_indh kvi on (kvi.vare_id = kv.id) JOIN kat_vare_placering kvp on (kvp.v_id = kv.id) LEFT JOIN kat_billede kb ON (kb.vare_id = kv.id) WHERE (kvp.g_id = "&nn("kid")&") AND (kvi.sprog_id = "&sprogid&") AND (kvi.online = 1) ORDER BY kvp.rakkefolge ASC
Hvis du kun vil have en række uanset antallet af billeder, så har du umiddelbart to muligheder:
1. lad være med at joine til billedetabellen 2. lav en aggregat funktion på et felt i billedetabellen (f.eks. COUNT) og gruppér på alle andre felter i dit resultat.
LEFT JOIN sikrer bare at du får alle berørte rækker fra "venstre"-tabellen (den tabel der står på venstre side af LEFT JOIN) med i dit resultat uanset om "højre"-tabellen indeholder relaterede data eller ej. Hvis "højre"-tabellen ikke indeholder data, vil alle kolonner fra denne tabel blot indeholde NULL i det samlede resultat. Indeholder "højre"-tabellen derimod flere rækker pr. række i "venstre"-tabellen, så vil resultatet indeholde fulde rækker for alle de, til "venstre"-tabellen, relaterede rækker i "højre"-tabellen.
? SELECT DISTINCT kvp.rakkefolge,kvi.navn,kvi.kort_beskr,kvp.g_id,kb.billede, kv.id AS vareID FROM kat_vare kv JOIN kat_vare_indh kvi on (kvi.vare_id = kv.id) JOIN kat_vare_placering kvp on (kvp.v_id = kv.id) LEFT JOIN kat_billede kb ON (kb.vare_id = kv.id) WHERE (kvp.g_id = "&nn("kid")&") AND (kvi.sprog_id = "&sprogid&") AND (kvi.online = 1) ORDER BY kvp.rakkefolge ASC
Ja, enten en forspørgsel mere i databasen for hver vare eller iterér over et samlet resultat (med både vare og billededata) og vis dine billeder (hvis det er det du vil ifm. visning af hver vare), indtil varens id skifter. Den sidste løsning er ikke speciel optimal, da du potentielt set transporterer en masse redundante data i de tilfælde hvor der er flere billeder til en vare.
Et tredie alternativ (som jeg ikke har nogen erfaring med og viden om hvorvidt det faktisk kan lade sig gøre), er at lave et shaped resultat, hvor du har et resultat med delresultater til hver række (dvs. i dit tilfælde billeder til en given vare). Men som sagt, så er det ikke noget jeg har prøvet, så der kan jeg ikke hjælpe :(
19/12-2007 00:29:46 >> DISTINCT virker på hele rækkens data og hvis billederne er forskellige, så vil rækken medtages i resultatet selvom varens data er ens.
Hm... ok, kan du ikke prøve at vise den kode hvor du har skrevet SQL-sætningen (jeg antager du har flettet den ind i noget VBScript eller sådan noget)?
sql="SELECT d.*, e.beskrivelse FROM (SELECT a.id as gID, a.parent_id, a.rakkefolge, a.billede,b.navn, b.url, b.grp_id,(SELECT COUNT(*) FROM kat_vare_placering WHERE g_id = a.id) AS antalKommentarer FROM kat_varegrp AS a INNER JOIN kat_varegrp_indh AS b ON b.grp_id = a.id WHERE a.butik_id = "&butikID&" AND b.sprog_id = "&sprogid&" AND b.online = 1 GROUP BY a.id, a.parent_id, a.rakkefolge,a.billede, b.navn, b.url, b grp_id) AS d INNER JOIN kat_varegrp_indh AS e ON e.id = d.gID ORDER BY d.parent_id, d.rakkefolge"
Der må være et problem med kobling af relationen mellem e (i den ydre forspørgsel) og b (i den indre forspørgsel). Det jeg har gjort er at koble e med a i stedet for e med b (det er jo i b beskrivelsen ligger), så derfor skal id'et for b også medtages i den indre query, så jeg kan koble e med b via dette id i den ydre forspørgsel.
(Jeg tillader mig lige at bruge min egen version af SQL-sætningen, da jeg lettere kan overskue denne - jeg håber ikke du synes det er for træls at skulle omskrive den hele tiden :-)):
SELECT d.*, e.beskrivelse, e.billede FROM ( SELECT a.id AS gID, a.parent_id, a.rakkefolge, b.navn, b.url, b.grp_id, b.id AS bID, (SELECT COUNT(*) FROM kat_vare_placering WHERE g_id = a.id) AS antalKommentarer FROM kat_varegrp AS a INNER JOIN kat_varegrp_indh AS b ON b.grp_id = a.id WHERE a.butik = "&butikID&" AND b.sprog_id = "&sprogid&" AND b.online = 1 GROUP BY a.id, a.parent_id, a.rakkefolge, b.navn, b.url, b.grp_id, b.id ) AS d INNER JOIN kat_varegrp_indh AS e ON e.id = d.bID ORDER BY d.parent_id, d.rakkefolge
Jeg er slet ikke sikker på at dette er årsagen til fejlen, men det er da under alle omstændigheder mere korrekt end det andet ;-)
Det er da grov som jeg reintroducerer fejl i den SQL-sætning! Prøver lige igen, med udgangspunkt i din:
SELECT d.*, e.beskrivelse FROM ( SELECT a.id as gID, a.parent_id, a.rakkefolge, a.billede, b.navn, b.url, b.grp_id, b.id AS bID, (SELECT COUNT(*) FROM kat_vare_placering WHERE g_id = a.id) AS antalKommentarer FROM kat_varegrp AS a INNER JOIN kat_varegrp_indh AS b ON b.grp_id = a.id WHERE a.butik_id = "&butikID&" AND b.sprog_id = "&sprogid&" AND b.online = 1 GROUP BY a.id, a.parent_id, a.rakkefolge, a.billede, b.navn, b.url, b.grp_id, b.id ) AS d INNER JOIN kat_varegrp_indh AS e ON e.id = d.bID ORDER BY d.parent_id, d.rakkefolge
Aha! Det var nok en god idé at tage udgangspunkt i din, for jeg fandt lige ud af at der manglede et punktum mellem b og grp_id lige inden den afsluttende parantes. Jeg har rettet i den ovenstående, incl. join på den rigtige tabel ifht. beskrivelsen.
ja jeg valgte den nemme løsning for nu. Har lavet et loop i mit loop hvor jeg udskriver billederne. En dum løsning, men den sql kunne jeg ikke gennemskue, desværre.
Fair nok, det er vel også dig der skal vedligeholde den i fremtiden og så duer det jo ikke, hvis du ikke ved hvad du har lavet :-)
Synes godt om
Ny brugerNybegynder
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.