PostgreSQL: проблемы с join + external-join + sub-select для сравнения значений. - PullRequest
0 голосов
/ 26 октября 2011

Я использую postresql, но я очень плохо умею создавать SQL-запросы.У меня есть этот запрос, и он работает:

SELECT handhistories FROM handhistories 
JOIN pokerhands using (pokerhand_id)  
JOIN gametypes using (gametype_id)
RIGHT OUTER JOIN playerhandscashkeycolumns using (pokerhand_id)
     WHERE pokerhands.site_id=0  
     AND pokerhands.numberofplayers>=5 and  pokerhands.numberofplayers<=7
     AND (bigblind = 2 OR bigblind = 4 )
     AND player_id in 
        (SELECT player_id FROM playerhandscashkeycolumns GROUP BY player_id
         HAVING AVG(case didvpip when true then 100::real else 0 end) <= 20 )

, но я также хочу ограничить последнее «наличие» снизу, так что это будет что-то вроде этого, но, конечно, это не работает.

SELECT handhistories FROM handhistories 
JOIN pokerhands using (pokerhand_id)  
JOIN gametypes using (gametype_id)
RIGHT OUTER JOIN playerhandscashkeycolumns using (pokerhand_id)
       WHERE pokerhands.site_id=0  
       AND pokerhands.numberofplayers>=5 and  pokerhands.numberofplayers<=7
       AND (bigblind = 2 OR bigblind = 4 )
       AND player_id in 
        (SELECT player_id FROM playerhandscashkeycolumns GROUP BY player_id
         HAVING AVG(case didvpip when true then 100::real else 0 end) <= 20
         AND  HAVING AVG(case didvpip when true then 100::real else 0 end) > 10 )

как "сохранить" значение, которое есть после того, как я смогу сравнить его снизу?Спасибо всем.

Ответы [ 2 ]

1 голос
/ 26 октября 2011

Это в основном то, на что @ wildplasser уже указал
.. минус ошибка с BETWEEN
.. plus JOIN вместо IN конструкции, которая обычно быстреев PostgreSQL.
.. проще для чтения

SELECT handhistories
FROM   handhistories
JOIN   pokerhands USING (pokerhand_id)  
JOIN   gametypes USING (gametype_id)
RIGHT  JOIN playerhandscashkeycolumns USING (pokerhand_id)
JOIN   (
    SELECT player_id
    FROM   playerhandscashkeycolumns
    GROUP  BY player_id
    HAVING avg(CASE WHEN didvpip THEN 100::real ELSE 0 END) >  10
    AND    avg(CASE WHEN didvpip THEN 100::real ELSE 0 END) <= 20
    ) p USING (player_id)
WHERE  pokerhands.site_id = 0  
AND    pokerhands.numberofplayers BETWEEN 5 AND 7
AND    bigblind IN (2,4);

Вы можете определить некоторые столбцы, например pokerhands.site_id, но не другие, например handhistories, возможно, вы захотите очистить это.1014 *

1 голос
/ 26 октября 2011

Будет ли BETWEEN работать для вас?

HAVING AVG(case didvpip when true then 100::real else 0 end) BETWEEN 10 AND 20

(Кстати: уродливый синтаксис SQL, повторное использование ключевого слова AND)

UPDATE: также может использоваться для упрощения остальной части вашего запроса:

AND pokerhands.numberofplayers BETWEEN 5 AND 7
AND bigblind IN ( 2, 4 )
...