Several games Guide

PQL by example

Twelve tiny queries that between them cover most of what PQL does: equity, draws, board textures, histograms, split pots, weights and real solver ranges. Each one runs in your browser in about a second.

12 runnable queries. The stated numbers are what we measured, not a promise. Monte-Carlo runs wobble, and the solver-referenced ranges move when we re-solve. Run the cells for today's figures.

Every PQL query has the same shape. You SELECT an aggregator over a poker function, FROM a game and some player ranges. Everything else is detail. Run the cells top to bottom, because each one adds a single idea to the one before it.

1. How big a favorite is AA preflop?

select avg(equity(hero)) from game='holdem', hero='AA', villain='**'

equity(hero) is all-in equity over a full runout. villain='**' means any two cards, and avg(...) averages across trials.

About 85%.

Run in the PQL engine →

2. The classic race: AK suited against QQ

select avg(equity(hero)) from game='holdem', hero='AKs', villain='QQ'

About 46%. The pair is the favorite, but barely.

Run in the PQL engine →

3. How often do two suited cards flop a flush draw?

select count(hasFlushDraw(hero, flop)) from game='holdem', hero='AhKh', villain='**'

count(...) is the fraction of trials where the predicate holds. Draw functions want you to name a street.

About 11%, so roughly one flop in nine.

Run in the PQL engine →

4. How often does JT flop a straight draw?

select count(hasStraightDraw(hero, flop)) from game='holdem', hero='JsTd', villain='**'

Gutshots count here. Use hasOpenEnder if you only want the seven-outs-or-more draws.

About 27%.

Run in the PQL engine →

5. What does AK suited make by the river?

select histogram(handType(hero, river)) from game='holdem', hero='AKs', villain='**'

histogram(...) buckets every trial by the value of the expression, here the final hand class.

One pair leads at about 43%, then two pair at 22% and high card at 18%.

Run in the PQL engine →

6. How often does the board pair by the river?

select count(pairedBoard()) from game='holdem', hero='**', villain='**'

Board functions take no player argument, so nobody needs a hand.

Just under half, 49-50%. Swap in monotoneBoard() and it drops to about 0.25%.

Run in the PQL engine →

7. A CASE expression: flush-draw EV at 3:1

select avg(case
    when winsHi(hero) then 3.0
    when tiesHi(hero) then 1.0
    else -1.0
  end) as ev_per_dollar
from game='holdem',
     hero='AhKh',
     villain='JsJc',
     board='2h7h9c2s'

A fixed hero, a fixed villain and a turn board leave few enough runouts that the engine stops sampling and enumerates them instead. Every river is counted exactly once, so this answer carries no sampling error at all.

Exactly +0.27 per dollar called.

Run in the PQL engine →

8. PLO: AAKK double-suited against three random hands

select avg(equity(hero)) from game='omahahi', hero='AAKK$ds', v1='****', v2='****', v3='****'

$ds is the double-suited shape macro. '****' is any four cards.

About 45% of a four-way pot, close to double the 25% a random hand would hold.

Run in the PQL engine →

9. Omaha Hi-Lo: how often does A-2-3-4 scoop?

select count(scoops(hero)) from game='omaha8', hero='As2h3h4h', villain='****'

scoops(hero) is true only when hero wins the high and the low outright.

About 39%.

Run in the PQL engine →

10. Real solver ranges: BTN open against a BB 3-bet

select avg(equity(btn_open)) as btn,
       avg(equity(bb_3bet)) as bb
from game='omahahi',
     btn_open='#6m/rfi/btn',
     bb_3bet='#6m/3b/bb/btn'

#... references pull frequency-weighted preflop ranges straight from this site's PLO solves. A hand that 3-bets 40% of the time is sampled at 40% weight.

The 3-bettor comes out around 57-58%.

Run in the PQL engine →

11. Weighted ranges: four parts KK to one part AA

select avg(equity(hero)) from game='holdem', hero='AA@25,KK', villain='**'

@25 means 25% of full weight, and an unweighted atom is implicitly @100, so KK gets sampled four times as often as AA.

About 83%, sitting between KK against a random hand (82%) and AA against one (85%), much nearer KK.

Run in the PQL engine →

12. Filtering trials with WHERE

select count(minFlopHandCategory(hero, toppair)) as top_pair_or_better
from game='holdem',
     hero='AhKh',
     villain='**'
where boardsuitcount(flop) = 2 and not pairedBoard(flop)

WHERE throws trials away before the aggregator ever sees them. This one keeps only two-tone, unpaired flops.

About 35% of the flops that survive the filter.

Run in the PQL engine →

That is the whole model. Functions run once per trial, aggregators run across trials, and WHERE decides which trials count. The two longer guides use nothing beyond this.

PQL computes entirely in your browser, no install or account. New to it? See the PQL syntax reference, open the PQL engine, or browse all recipes.

More guides

Go beyond queries: study real PLO solutions

Preflop ranges, postflop strategy and practice mode across all 1,755 PLO flop textures. Free tier, no card required.

Try SolvePoker Free