PostgreSQL:连接问题外连接 +子选择以比较值。

发布于 2024-12-11 20:32:36 字数 1316 浏览 0 评论 0原文

我正在使用 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 )

但我也想限制底部的最后一个“having”,所以它将是这样的,但当然它不起作用。

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 )

如何“保存”拥有之后的值,以便我也可以从底部进行比较? 谢谢大家。

I am using postresql but i am realy bad at construting sql queries.
I have this query and it works:

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 )

but i also want to limit the last "having" from the bottom so it will be something like this, but ofcourse it does not work.

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 )

how to "save" value that is after the having so i can compare it also from the bottom?
Thank you all.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

—━☆沉默づ 2024-12-18 20:32:36

这主要是@wildplasser已经指出的
..减去 BETWEEN
的错误
..加上 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,您可能需要清理它们。

This is mostly what @wildplasser already pointed out
.. minus the mistake with BETWEEN
.. plus JOIN instead of IN construct, which is usually faster in PostgreSQL.
.. easier to read

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);

You table-qualify some columns, like pokerhands.site_id, but not others, like handhistories, you might want to clean that up.

很酷又爱笑 2024-12-18 20:32:36

BETWEEN 适合你吗?

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

(顺便说一句:丑陋的 SQL 语法,重复使用 AND 关键字)

更新:也可以用来简化查询的其余部分:

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

Would BETWEEN work for you ?

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

(BTW: ugly SQL syntax, reusing the AND keyword)

UPDATE: can also be used to simplify the rest of your query:

AND pokerhands.numberofplayers BETWEEN 5 AND 7
AND bigblind IN ( 2, 4 )
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文