WN

WN (https://www.wn.se/forum/index.php)
-   Serversidans teknologier (https://www.wn.se/forum/forumdisplay.php?f=4)
-   -   SQL SUM() i WHERE kriteria (https://www.wn.se/forum/showthread.php?t=29069)

blixtsystems 2008-05-02 21:42

Har ett litet MySQL problem.
Jag behöver summan av ett fält i en tabell för att använda i mina WHERE kriteria, men jag är lite av en kratta på SQL och vet inte om det går och isåfall hur.

Har testat följande:
Kod:

SELECT DISTINCT hand.id
FROM handdata_hand AS hand,
 handdata_players AS players,
 handdata_forced AS forced
WHERE players.hand_id=hand.id
AND forced.hand_id=hand.id
AND ((players.player_stack / (SELECT SUM(amount)
  FROM forced
  WHERE hand_id = hand.id )) BETWEEN 0 AND 5)

Uppenbarligen kan jag inte använda alias i en subquery och får:
Table 'handdata.forced' doesn't exist

Det är egentligen en mycket längre fråga och använder jag inte alias i min subquery så relaterar inte resultatet till rätt "hand.id".

Kör jag innan "FROM" så vet jag inte hur jag skall kunna använda värdet under "WHERE", t.ex.:
Kod:

SELECT DISTINCT hand.id, SUM(forced.amount) AS forcedamount
FROM handdata_hand AS hand,
 handdata_players AS players,
 handdata_forced AS forced
WHERE players.hand_id=hand.id
AND forced.hand_id=hand.id
AND ((players.player_stack / forcedamount) BETWEEN 0 AND 5)

Det ger mig: Unknown column 'forcedamount' in 'where clause'

Någon som har en idé?

WizKid 2008-05-02 21:44

HAVING är nog det du letar efter.

blixtsystems 2008-05-02 21:56

Supertack för det snabba och utmärkta svaret!!

Detta verkar fungera:
Kod:

SELECT DISTINCT hand.id, SUM( forced.amount ), players.player_stack
FROM handdata_hand AS hand, handdata_players AS players, handdata_forced AS forced

WHERE players.hand_id = hand.id
AND forced.hand_id = hand.id
GROUP BY hand.id
HAVING (
(
players.player_stack /
 SUM( forced.amount )
)
BETWEEN 0
AND 5
)


blixtsystems 2008-05-03 00:17

HAVING verkar ju vara rätt lösning, men jag får inte riktigt till det.
Denna frågan kör ok:
Kod:

SELECT DISTINCT hand.id, SUM( forced.amount ), players.player_stack
FROM handdata_hand AS hand, handdata_players AS players, handdata_forced AS forced

WHERE players.hand_id = hand.id
AND forced.hand_id = hand.id
GROUP BY hand.id
HAVING (
(
players.player_stack /
SUM( forced.amount )
)
BETWEEN 0
AND 5
)


Dock så måste jag sätta den snutten i sitt sammanhang för att kunna testa om resultatet är korrekt...och det är det inte.
Följande är hela frågan som den ser ut nu:
Kod:

SELECT DISTINCT hand.id, SUM( forced.amount ) as amount, players.player_stack as stack
FROM handdata_hand AS hand,
 handdata_card AS card1,
 handdata_card AS card2,
 handdata_players AS players,
 handdata_forced AS forced,
 handdata_position AS position
WHERE card1.hand_id=hand.id
AND card2.hand_id=hand.id
AND players.hand_id=hand.id
AND position.hand_id=hand.id
AND forced.hand_id=hand.id
AND card1.player_id=players.player_id
AND card2.player_id=players.player_id
AND ((card1.value LIKE 'A_' AND card2.value LIKE 'Q_')
        AND (card1.type = 'showdown' OR card1.type = 'deal')
        AND (card2.type = 'showdown' OR card2.type = 'deal'))
AND (position.seatcount BETWEEN 1 AND 10)
AND (players.player_seat BETWEEN position.SB AND position.UTG)
GROUP BY hand.id
HAVING (
(
stack /
SUM( amount )
) BETWEEN 0 AND 5)


HAVING verkar fungera, men "amount" värdet är fel.

Kollar jag resultatet så jag ser "hand_id" samt "amount" för varje rad.
T.ex. har jag en rad med id 3914 och amount 900, men kör jag
"SELECT amount FROM handdata_forced WHERE hand_id = 3914"
så får jag två rader, en med 75.00 och en med 150.00.

Hur kan det komma sig att amount inte är 225 då?

blixtsystems 2008-05-03 20:43

Äsch...tydligen så går det inte att referera till ett tabellnamn med alias i en subquery om det faktiskt används som referens till en tabell, men om det refererar till ett värde i en tabell så går det bra.


(SELECT SUM(amount)
FROM forced
WHERE hand_id = hand.id )
ger "Table 'handdata.forced' doesn't exist"

Men
(SELECT SUM(handdata_forced.amount) FROM handdata_forced WHERE hand_id=hand.id)
klagar inte på referensen till "hand.id" och fungerar!??

Speciellt snabbt verkar det inte bli och HAVING verkar snabbare men jag lyckas inte få korrekta resultat med den metoden :(

eg0master 2008-05-04 08:44

Ska du verkligen ha ett SUM-anrop i having-delen? Så var ju inte dit ursprungliga exempel konstruerat.

blixtsystems 2008-05-04 09:25

Jag tycker också det ser lite överflödigt ut men fick det från w3schools exempel för GROUP BY och HAVING: http://www.w3schools.com/sql/sql_groupby.asp
Jag har även testat att bara köra amount i HAVING, och det verkar ge samma resultat.

Nu har jag dock lyckats få upp hastighheten på min subquery.
Istället för att köra den i mina WHERE kriteria så kör jag det i FROM vilket gjorde en väldig skillnad:
Kod:

SELECT DISTINCT hand.id as handid
FROM handdata_hand AS hand,
 handdata_card AS card1,
 handdata_card AS card2,
 handdata_players AS players,
 handdata_forced AS forced,
 handdata_position AS position,
        (SELECT SUM(amount) AS sum, hand_id FROM handdata_forced GROUP BY hand_id) AS amount
WHERE card1.hand_id=hand.id
AND card2.hand_id=hand.id
AND players.hand_id=hand.id
.....
AND (
players.player_stack /
amount.sum
) BETWEEN 10 AND 11



Alla tider är GMT +2. Klockan är nu 20:01.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson