Vinnaren i pepparkakshustävlingen!
2008-03-25, 23:14
  #1
Medlem
mannenmedhattens avatar
Jag plockar ut data från tre tabeller i samma sql-sats och den visar korrekt när något finns inlaggt i databasen på de posterna. Men om däremot en post skulle vara tom - i det här fallet COUNT(id) - så syns inte det resultatet. Alltså inget av det som ska skrivas ut på det resultatet skrivs ut = blankt fält.

Kod:
$sql "SELECT f.id AS id, f.title AS title, f.description AS description, f.username AS username, f.launchdate AS launchdate, COUNT(v.id) AS votes, COUNT(c.id) AS comments
        FROM features f, votes v, comments c
        WHERE f.status=3 AND v.deleted=0 AND v.id=f.id AND c.deleted=0 AND c.id=f.id
        GROUP BY f.id
        ORDER BY f.launchdate DESC"


Som sagt. Det fungerar om den hittar nått på alla, men hittar den inte på en av dem så blir det inget utskrivet.. Hoppas ni förstår problemet.

Finns det något sätt att gå omkring detta fenomen?

Tack på förhand
Citera
2008-03-25, 23:49
  #2
Medlem
Använd join istället.
Kod:
SELECT 
   f
.id AS id
   
f.title AS title
   
f.description AS description
   
f.username AS username
   
f.launchdate AS launchdate
   
COUNT(v.id) AS votes
   
COUNT(c.id) AS comments
FROM 
   features f
LEFT JOIN 
   votes v
ON
   v
.id=f.id
LEFT JOIN
   comments c
ON
   c
.id=f.id
WHERE 
   f
.status=AND v.deleted=AND c.deleted=0
GROUP BY f
.id
ORDER BY f
.launchdate DESC 
Är ganska trött nu men tror att det ska funka...
Citera
2008-03-26, 08:53
  #3
Medlem
mannenmedhattens avatar
Sjysst! Det funkade nästan direkt. Var tvungen att ta bort c.deleted=0 från
Kod:
WHERE 
   f
.status=AND v.deleted=AND c.deleted=

Tack så mycket! Nu får det bli att läsa på mer om join - jag vet faktiskt inte så värst mycket om det..
Citera
2008-03-26, 11:44
  #4
Medlem
gadzooxs avatar
Citat:
Ursprungligen postat av mannenmedhatten
Tack så mycket! Nu får det bli att läsa på mer om join - jag vet faktiskt inte så värst mycket om det..
Vettig artikel: http://en.wikipedia.org/wiki/Join_%28SQL%29
Citera
2008-03-26, 11:50
  #5
Avstängd
Edwardss avatar
Citat:
Ursprungligen postat av DJOMF
Använd join istället.
Kod:
SELECT 
   f
.id AS id
   
f.title AS title
   
f.description AS description
   
f.username AS username
   
f.launchdate AS launchdate
   
COUNT(v.id) AS votes
   
COUNT(c.id) AS comments
FROM 
   features f
LEFT JOIN 
   votes v
ON
   v
.id=f.id
LEFT JOIN
   comments c
ON
   c
.id=f.id
WHERE 
   f
.status=AND v.deleted=AND c.deleted=0
GROUP BY f
.id
ORDER BY f
.launchdate DESC 
Är ganska trött nu men tror att det ska funka...

Sög inte LEFT JOIN massa CPU?
Citera
2008-03-26, 19:59
  #6
Medlem
mannenmedhattens avatar
Hej igen.. i och med att det är samma sql-sats som gäller så frågar jag i samma tråd. Man kan väl säga att frågan är utökad..

Om jag skulle vilja sortera efter den som har flest COUNT(v.id) as votes. DVS den som har flest röster på sig. Hur gör jag då? Det fungerade inte att bara köra:

Kod:
[...]
ORDER BY COUNT(v.id)
[...] 
eller
Kod:
[...]
ORDER BY votes
[...] 
Citera
2008-03-26, 21:34
  #7
Medlem
mannenmedhattens avatar
HALLÅ!

SQLen fungerar inte. Jag tror inte ens den första som jag skrev in fungerar riktigt rätt. När det börjar bli flera poster att räkna på (COUNT()) så sätter den helt plötsligt både resultatet för comments och votes till samma :S Det verkar hända när COUNT(c.id) blir mer än 4 poster.

Det är när jag ska räkna ur hur många som har samma referensid. I detta fall COUNT(c.id) och COUNT(v.id). Det är där det blir fel tror jag. Finns det andra sätt att göra det jag vill? (nu hoppas jag ni förstår vad jag vill med )

Tack på förhand
Citera
2008-03-26, 23:02
  #8
Medlem
mannenmedhattens avatar
Väldigt simpelt förklarat ser mina tabeller ut såhär:

Kod:
Tabell A:
+--------------------------------------------------+
| id | namn | beskrivning | anamn | datum | status |
|--------------------------------------------------|
| 1  |  X   |   dansar    | kalle | 080326|   2    |
|--------------------------------------------------|
| 2  |  Y   |   pratar    | kalle | 080325|   2    |
|--------------------------------------------------|
| 3  |  Z   |   springer  | oskar | 080324|   2    |
+--------------------------------------------------+

Tabell B:
+--------------------------------------------------+
| id | aid  |  anamn  |   text   | datum | status  |
|--------------------------------------------------|
| 1  |  1   |  oskar  |   coolt  | 080326|   0     |
|--------------------------------------------------|
| 2  |  1   |  nils   |   najs   | 080326|   0     |
|--------------------------------------------------|
| 3  |  3   |  kalle  |   bra    | 080326|   0     |
|--------------------------------------------------|
| 4  |  2   |  kalle  |  häftigt | 080325|   0     |
+--------------------------------------------------+

Tabell C:
+------------------------------+
|aid|  anamn  | datum | status |
|------------------------------|
| 1 |  nils   | 080326|   0    |
|------------------------------|
| 1 |  oskar  | 080326|   0    |
|------------------------------|
| 1 |  kalle  | 080326|   0    |
|------------------------------|
| 2 |  oskar  | 080326|   0    |
|------------------------------|
| 3 |  oskar  | 080326|   0    |
+------------------------------+

Sammanfattning:
Tabell B och C är relationstabeller till Tabell A. Jag vill plocka ut ALLA värden och sedan skriva ut dem, på något sätt. Jag vill också räkna ut hur många poster som har en relation till posterna i Tabell A.

Exempel:
Jag väljer id=1 i Tabell A. Hur många har en relation till det värdet i Tabell B? Jo aid=1, 2 gånger. Jag vill därmed att siffran 2 ska skrivas ut.

Vi gör detsamma mellan Tabell A och C med samma id=1. Då får vi aid=1, 3 gånger - och därmed ska siffran 3 skrivas ut.

Skulle vi ta id=3 i Tabell A skulle vi få värdena 1 och 1.

----------

Jag hoppas ni förstår vad det är jag vill åstadkomma. Ni har ju också den information jag skrivit i tidigare poster tillhands så jag hoppas ni kan hjälpa mig

(lika bra att skapa en ny post i tråden istället för att redigera den som gjorde tidigare då det blev rätt så mycket information/kod i denna post)
Citera
2008-03-26, 23:18
  #9
Medlem
Citat:
Ursprungligen postat av mannenmedhatten
HALLÅ!

SQLen fungerar inte. Jag tror inte ens den första som jag skrev in fungerar riktigt rätt. När det börjar bli flera poster att räkna på (COUNT()) så sätter den helt plötsligt både resultatet för comments och votes till samma :S Det verkar hända när COUNT(c.id) blir mer än 4 poster.

Det är när jag ska räkna ur hur många som har samma referensid. I detta fall COUNT(c.id) och COUNT(v.id). Det är där det blir fel tror jag. Finns det andra sätt att göra det jag vill? (nu hoppas jag ni förstår vad jag vill med )

Tack på förhand

Problemet är att du bara kan ha en GROUP BY, och då så skiter allting sig eftersom du då får (efter att det har grupperat allting så att säga) en massa poster poster, en för varje kommentar och varje röst typ, och när du sen gör COUNT(v.id) så räknar du egentligen alla rader, och räknar alltså alla röster plus alla kommentarer. Typ nåt sånt. Jag tror att du behöver använda nestade SQL-satser för att åstadkomma det jag tror att du vill åstadkomma, testa tex:

Kod:
SELECT  
   f.id AS id,  
   f.title AS title,  
   f.description AS description,  
   f.username AS username,  
   f.launchdate AS launchdate,  
   COUNT(v.id) AS votes,
   sub.comments AS comments
FROM  
   features f
JOIN votes v ON f.id = v.id 
JOIN 
(
   SELECT
      f.id AS id,
      COUNT(c.id) AS comments
   FROM 
      features f JOIN comments c ON f.id = c.id
   WHERE 
      c.deleted = 0
   GROUP BY id
) AS sub
ON sub.id = f.id 
WHERE  
   f.status=3 AND v.deleted=0 
GROUP BY f.id 
ORDER BY votes
Citera
2008-03-26, 23:47
  #10
Medlem
mannenmedhattens avatar
Tack för snabbt och bra svar dbshw!

Nu börjar det likna något. Tyvärr om tex COUNT(c.id)=0/NULL så visas inte de resultaten! COUNT(v.id) kommer alltid att vara minst 1 så det är inga bekymmer.
__________________
Senast redigerad av mannenmedhatten 2008-03-26 kl. 23:54.
Citera
2008-03-27, 00:01
  #11
Medlem
Citat:
Ursprungligen postat av mannenmedhatten
Tack för snabbt och bra svar dbshw!

Nu börjar det likna något. Tyvärr om tex COUNT(c.id)=0/NULL så visas inte de resultaten! COUNT(v.id) kommer alltid att vara minst 1 så det är inga bekymmer.

Du har så rätt så, några LEFT JOINs är nog nödvändiga, annars så försvinner det features som saknar kommentarer eller saknar röster. Det här tror jag borde fixa biffen:

Kod:
SELECT  
   f.id AS id, 
   f.title AS title,  
   f.description AS description,  
   f.username AS username,  
   f.launchdate AS launchdate,  
   COUNT(v.id) AS votes,
   sub.comments AS comments
FROM  
   features f
LEFT JOIN votes v ON f.id = v.id
JOIN
(
   SELECT
      f.id AS id,
      COUNT(c.id) AS comments
   FROM 
      features f LEFT JOIN comments c ON f.id = c.id
   WHERE 
      c.deleted = 0 OR c.deleted IS NULL
   GROUP BY id
) AS sub
ON sub.id = f.id 
WHERE  
   f.status=3 AND (v.deleted=0 OR v.deleted IS NULL)
GROUP BY f.id 
ORDER BY launchdate

Om du alltid kan garantera att varje feature har minst en vote så kan du ändra den första LEFT JOIN till en vanlig JOIN, och ta bort kontrollen på att v.deleted IS NULL i slutet, tror jag.

Spontant känns det dock som att det borde finnas ett smidigare sätt att räkna både röster och kommentarer utan att behöva ha nestade SELECT-satser, även om jag inte kan komma på vad det är. Kanske genom att använda nån annan typ av JOIN på nåt finurligt sätt.
Citera
2008-03-27, 00:10
  #12
Medlem
mannenmedhattens avatar
Oavsett om det är det smidigaste sättet eller inte så är du grym!!

Jag trodde jag var något sådär duktigt på sql men när jag ser det du skriver så inser jag hur mycker jag har kvar att lära - men det är kul att se fram emot nya grejer

Det ser ut som att det ska fungera nu och jag tackar dig än en gång, och självklart de andra som svarat i tråden! Tack
Citera

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback