Documente Academic
Documente Profesional
Documente Cultură
CONSULTAS SQL EN LA
BASE DE DATOS DE
POKER TRACKER
por Spainfull
Marzo 2007
Índice
CÓMO REALIZAR CONSULTAS SQL EN LA BASE DE DATOS DE POKER TRACKER ......1
PARTE I. USAR MICROSOFT ACCESS PARA HACER CONSULTAS ...................................................... 3
PARTE II. LA BASE DE DATOS DE POKER TRACKER EN DETALLE ...................................................... 7
PARTE III. TUTORIAL PARA CREAR CONSULTAS SQL ................................................................. 21
Este artículo tiene dos objetivos principales: explicar la manera de obtener más información de
nuestra base de datos Access de Poker Tracker (en adelante, PT) a través de consultas SQL
(http://es.wikipedia.org/wiki/SQL) y detallar la estructura de las tablas de esta base de datos
para saber dónde hacer las consultas. Está orientado hacia los usuarios del PT que tienen un
nivel básico de manejo de la informática (o sea, ni puta idea) y quieren obtener datos que
actualmente no muestra el programa. Bueno, si no quieres más información, quizás tengas la
curiosidad de saber cómo funciona por dentro PT y le pierdas el miedo a esto de los
ordenadores. En los foros (http://www.pokertracker.com/forum/) de PT hay un hilo
(http://www.pokertracker.com/forum/viewtopic.php?t=4189) en inglés que me ha servido de
base para este artículo y en estos foros, además, puedes encontrar consultas SQL hechas por
usuarios de PT.
Por defecto, el programa PT almacena los datos que captura de las diferentes salas de póquer
en un archivo de base de datos Access. Éste archivo tiene la extensión “.mdb” y no es más que
una manera de guardar la información. Esta información la obtiene PT de los historiales de las
manos que se almacenan en nuestro disco duro en los directorios de las aplicaciones de las
salas de póquer creados a tal efecto (la ruta que tenemos que poner en las ventanas de auto-
import del PT para que pueda leer las manos). Lo que hace PT es leer esos ficheros de texto
que contienen las manos jugadas, interpretar la información que de ellos se puede sacar
(jugadores, stacks, nuestras cartas de mano, cartas comunitarias, apuestas, ganador de la
mano, etc.) y escribirla en la base de datos de manera apropiada para que después pueda ser
procesada.
El método que voy a explicar a continuación solo es válido para aquellos que guardan los datos
del PT en una base de datos Access. Para realizar consultas SQL sobre ella, se necesita algún
programa que tenga esta función incluida. En principio, se pueden utilizar tanto Microsoft
Access como Microsoft Excel, aunque si no se dispone de estos programas, es posible bajarse
algún programa gratuito que nos permita hacer consultas Access como por ejemplo SQueAl
(http://www.freewarefiles.com/program_10_109_20139.html). En primer lugar mostraré
simplemente cómo hacer la consulta sin entrar a analizar en detalle otros aspectos un poco
más complejos que dejo para más adelante.
Antes de comenzar una advertencia: Microsoft Access es la aplicación nativa para las bases de
datos Access de PT, con lo que cualquier cambio que se haga sobre la tablas o borrado de
elementos por error pueden provocar daños irreparables que implicarían la inutilización de la
base de datos; así que cuida donde metes las zarpas y no pulses aceptar sin leer el mensaje. En
principio, si sigues los pasos indicados no hay ningún problema, pero por si acaso, ten siempre
una copia de seguridad de tu base de datos (basta con hacer una copia del archivo “.mdb”
donde tengas la base de datos).
La consulta que se va a hacer es la de parejas que han mejorado a trío en el flop. El código SQL
para esta consulta es el siguiente (ten en cuenta que esto no es un tutorial ni de SQL ni de
Access aunque posteriormente explicaré algunos conceptos, pero si quieres más información
la red está llena de tutoriales sencillos):
Para empezar, arranca la aplicación Microsoft Access. En el menú "Archivo" escoge la opción
"Abrir..." y en la ventana que se presenta, navega hasta seleccionar la base de datos sobre la
que quieras hacer la consulta. Por defecto, la base de datos de PT es "ptrack.mdb" (puede que
no aparezca la extensión “.mdb”) y se encuentra en la ruta: "C:\Archivos de programa\Poker
Tracker V2" (también se puede abrir pulsando dos veces sobre el archivo "ptrack.mdb" en el
explorador de Windows.
Cierra esta última ventana y nos quedamos con la ventana de consulta. Ahora debes pulsar el
icono "SQL" que se encuentra debajo de "Archivo" o seleccionar "Ver->Vista SQL".
Se puede guardar la consulta para no tener que copiarla cada vez que queremos obtener la
información; para ello basta
basta pulsar el icono del disquete o seleccionar ""Archivo
Archivo->Guardar"" y
darle un nombre a la consulta, almacenándose junto con el resto de consultas previas en el
apartado de "Consultas
"Consultas"" de la base de datos visto en la primera imagen. Lo que se guarda es el
texto
to de la consulta, no el resultado; si se quiere guardar el resultado habrá que copiarlo y
pegarlo en otra aplicación (Excel, Word, Block de notas, etc.).
Una última consideración, de las instrucciones SQL que se pueden ejecutar, solo ""SELECT"" no
tiene como
como resultado modificar las tablas de las bases de datos (simplemente muestra
información), así que no copiéis y ejecutéis consultas que incluyan palabras como ""DROP",",
"INSERT
INSERT", "UPDATE
UPDATE" o "DELETE
DELETE"" y, en general, consultas sospechosas no verificadas por otr
otros
usuarios más duchos en la materia. En el siguiente apartado explicaré en detalle las tablas de
la base de datos y un poco de SQL (no demasiado, necesitarás un tutorial más completo) para
que puedas hacer tus propias consultas.
Spainfull - Póquer
óquer yo lo valgo Page 6
Parte II. La base de datos de Poker Tracker en detalle
Para comprender mejor cómo funciona Poker Tracker y las instrucciones a escribir en la
consultas SQL, en el siguiente apartado detallaré la organización de la base de datos de
PT.
Para los menos iniciados en la informática, es preciso recordar que una base de datos no
es más que una manera de almacenar información. Cada tipo de base de datos tiene una
forma propia de guardar esos datos y acceder a ellos. Se hace así con el objetivo de
recuperar lo almacenado con mayor rapidez, mantener una gran cantidad de datos
eficientemente y para facilitar la inserción de nuevos elementos; todo esto es posible
porque hay implementados una serie de interfaces (protocolos, medios de comunicación
entre programas) que permiten realizar estas operaciones de manera mucho más eficaz
que si se guardaran los datos, por ejemplo, en un simple archivo de texto.
Hay muchos tipos de bases de datos. Seguro que te suenan palabras como Access,
Oracle, SQLServer, MySQL, PostgreSQL... Todas identifican bases de datos muy
diferentes entre sí, cuya construcción interna no se parece en absoluto, aunque tienen
cosas en común. Básicamente, todas ellas almacenan la información en tablas, cada una
de las cuales tiene una serie de campos que definen atributos de lo representado por la
tabla. La forma de acceder a estos datos es distinta en cada caso ya que suelen poseer su
propio lenguaje, pero las consultas SQL que voy a crear se pueden utilizar en todas ellas
con pocas modificaciones (SQL es el lenguaje base usado por la mayoría de bases de
datos de la actualidad).
Access no es diferente y también guarda los datos en tablas. Una tabla se identifica por
un nombre que debería ser descriptivo de la información que contiene. En cada tabla los
datos se agrupan en campos que contienen los detalles de lo que se quiere almacenar.
Por ejemplo, si se es un poco maníaco-obsesivo-exitoso y se desea tener una base de
datos de ligues, habría una tabla de nombre "Pibitas" (si es muy obsesivo
probablemente el nombre sería "Chochos") que contendría seguramente los campos
"Nombre", "Teléfono", "Altura", "Edad", "Peso", "Cara" (nota asignada de 1 a 10),
"Tetas" (nota asignada de 1 a 10), "Culo" (nota asignada de 1 a 10), "Sexo" (vamos, que
si folla) , "Casada" y "FechaPrimeraCita". Los campos son las columnas de la tabla y,
cada nueva conquista, sería una nueva fila en la tabla que tendría unos valores en los
campos que la definirían. Advertir que la elección de los campos ha sido totalmente
arbitraria; se podrían haber definido otros atributos o características (y no, no tengo una
tabla como ésta hecha).
Los campos pueden ser de distinto tipo dependiendo de la información que vayan a
guardar. Los tipos básicos disponibles son: numéricos (con decimales o sin decimales),
alfanuméricos (letras y números, es decir, texto), moneda, fechas y booleano (datos que
son verdadero o falso, por ejemplo "Sexo" y "Casada"). Como se puede comprobar,
hasta aquí no es nada complicado. Ahora que conoces las bases, voy a desmenuzar las
tablas de PT y el porqué de cada una.
En una base de datos suele haber más de una tabla para lograr definir los objetos que
participan en el problema a solucionar; además, los datos que contienen están
Ahora "solo" vas a aprender la estructura de la base de datos de PT, así que presta
atención. Si se abre la base de datos de PT tal y como comenté ayer, y se selecciona
"Tablas
Tablas"" en los "Objetos
"Objetos", ", aparece una imagen como la siguiente con todas las
tablas de PT:
La mayor parte de las tablas son bastante auto explicativas, y sus campos logran definir
cada aspecto que el programador de PT ha querido reflejar. Hay algunas tablas que son
de definición: de niveles, salas, ciegas, etc.; otras que detallan cada mano del juego con
todos los datos posibles; otras que son resumen de valores para que la recuperación y
visualización en PT sea más rápida (como por por ejemplo la tabla de las sesiones jugadas);
y, por último, otras que sirven para la configuración del programa.
Para ver los campos de cada tabla, basta con seleccionar la tabla de la que se quiere ver
su estructura y pulsar el icono de "Diseño
"Diseño"" o hacer clic con el botón derecho del ratón
sobre la tabla elegida y pulsar sobre "Vista
"Vista Diseño":
Diseño
Spainfull - Póquer
óquer yo lo valgo Page 8
Si se hace lo dicho, aparece una ventana que lista los campos que contiene la tabla y el
tipo de cada uno de los campos. También puede contener observaciones acerca del
contenido de cada uno de los campos que se utilizan para hacer aclaraciones sobre el
mismo (solo tiene valor informativo). Un apunte, en la creación de la mayor parte de las
tablas se define un campo identificador que distingue unívocamente a un unaa fila de la
tabla del resto de filas; la mayoría de las tablas de PT tienen un campo de este tipo, que
suele ser un entero positivo (se declara en la base de datos para que cada vez que se
añade una fila se incremente automáticamente, aunque éste es un de detalle
talle que no nos
importa demasiado). Estos identificadores son muy útiles para enlazar valores entre
tablas (esto se verá más claro en el siguiente capítulo en el que haré las consultas):
Voy a agrupar las tablas de PT según la función para la que han sido creadas. Ésta es
una clasificación que he establecido para que se vea más claramente la utilidad de cada
Spainfull - Póquer
óquer yo lo valgo Page 9
una de ellas, pero no significa que sean de distinto tipo sino simplemente que las he
ordenado para no mostrar todas seguidas; solo hay un tipo ún único
ico de tablas aunque se
usen para almacenar diferentes tipos de datos. Los datos de cash y torneos se guardan en
tablas separadas.
La mejor manera para seguir la explicación de las tablas es abrir en Access la base de
datos e ir abriéndolas conforme se detallan
detallan (basta con hacer doble click sobre la tabla
que se quiera visualizar).
♠ Tabla blind_structure.
blind_structure
Define los distintos niveles en un torneo. Contiene los campos siguientes:
Puede
ede que te preguntes por qué los valores están desordenados. Esto es debido a que en
cuanto PT lee un nivel nuevo de ciegas, añade una línea a esta tabla y le asigna un
identificador que comienza en 1 y se va incrementando automáticamente como expliqué
anteriormente.
eriormente. Seguramente inicié el PT con un torneo comenzado o la importación
automática de torneos la hizo de manera desordenada; esto no tiene ninguna importancia
ya que se sabe qué nivel es por el identificador; por ejemplo, el identificador 6
Spainfull - Póquer
óquer yo lo valgo Page 10
corresponde
correspon de al nivel de ciegas 150/300, y no importa el orden en el que esté insertada la
fila en la tabla.
♠ Tabla game_level.
game_level
Define las ciegas en las mesas de cash. Contiene los campos siguientes:
♠ Tabla hand_rank
nd_rank.
Define las posibles manos en el showdown en Holdem.
Holdem. Contiene los campos siguientes:
Como se puede apreciar, esta tabla sí está ordenada de peor a mejor jugada, esto es
debido a que es una tabla con los datos completos antes de capturar ningún dato el
programa, o rellenada automáticamente al crear una nueva base de datos (en Holdem el
Spainfull - Póquer
óquer yo lo valgo Page 11
ranking
ing de jugadas es fijo e inmutable).
♠ Tabla players.
Define a los jugadores en cada sala de póquer. Cada fila identifica a un jugador en una
sala. Se utilizará en todas las tablas que contengan datos de juego. Contiene los campos
siguientes:
Destacar que, como seguramente conoces, para agrupar las estadísticas de un jugador
que tiene datos de diferentes salas hay que utilizar los alias de PT. Ahora puedes ver
cómo funcionan. Cada jugador tiene una fila por sala en la que juega. Si se usan los
alias, a través de los campos "site_id
"site_id" y "alias_id
alias_id"" el programa sabe que son el
mismo jugador y combinará sus estadísticas.
Spainfull - Póquer
óquer yo lo valgo Page 12
♠ Tabla poker_sites.
Define las salas de póquer para las que funciona PT. Contiene los campos siguientes:
♣ Tablas de datos:
Almacenan los datos del juego en sí.
♠ Tabla game.
Define los detalles generales de cada mano de cash. Cada fila identifica una mano
jugada e importada en el PT. Contiene los campos siguientes:
Es un resumen de cada mano jugada. Los detalles por jugador están contenidos en la
tabla "game_players
"game_players".
♠ Tabla tourney_game.
tourney_game
Define los detalles generales de cada mano de torneo. Cada fila es una mano de torneo
jugada e importada por PT. Contiene los campos siguientes:
siguiente
Spainfull - Póquer
óquer yo lo valgo Page 14
• real_player_id:: identificador real del jugador (si se utilizan alias, éste será
real_player_id
el identificador del jugador en la sala, no su alias).
• players_saw_flop: jugadores que han visto el flop
players_saw_flop: flop.
• number_of_players:: número total de jugadores de la mano.
number_of_players
• heads_up: si se trata de un torneo Heads Up.
heads_up: Up
Como se puede comprobar, esta tabla es similar a la anterior pero usada para torneos.
♠ Tabla game_players.
game_players
Define los detalles de cada mano desde el punto de vista de cada jugador que participa
en la misma. Contiene los campos siguientes:
Spainfull - Póquer
óquer yo lo valgo Page 15
• won_hand:: 1 si el jugador ganó la mano, 0 si no.
won_hand
• session_id: identificador de la sesión en la que se circunscribe la mano.
session_id:
• off_the_button: número de posiciones de diferencia con el button.
off_the_button:
• number_of_players: número de jugadores en la mano.
number_of_players:
• big_blind_n: 1 si es big blind,
big_blind_n: blind 0 si no.
• small_blind_n: 1 si es small blind,
small_blind_n: blind, 0 si no.
• went_to_showdown_n: 1 si llegó con la mano hasta el final, 0 si no.
went_to_showdown_n:
• saw_flop_n: 1 si vió el flop,, 0 si no.
saw_flop_n:
• attempted_steal: 1 si intentó un robo, 0 si no.
attempted_steal:
• raised_first_pf: 1 si subió el primero antes del flop,, 0 si no.
raised_first_pf:
• real_player_id: identificador real del jugador (no su alias).
real_player_id:
• chip_count: dinero con el que el jugador comenzó la mano.
chip_count:
• ll_blind:: 1 si es la ciega kill en una mesa kill de UB, 0 si no.
ub_kill_blind
Hay muchos otros campos booleanos (valores cierto o falso, 0 ó 1) que definen cada
una de las posibles acciones que el jugador ha podido realizar en cada una de las calles
(call,, check-raise raise,, etc.) y que servirán para mostrar las estadísticas en las
raise, bet-raise
ventanas del PT.
♠ Tabla tourney_game_players.
tourney_game_players
Define los detalles de cada mano de torneo desde el punto de vista de cada jugador que
participa en la misma. Contiene los campos
campos siguientes:
Spainfull - Póquer
óquer yo lo valgo Page 16
• hand_rank_id:: identificador de la calidad de la jugada de la mano ganadora.
hand_rank_id
• all_in: si el jugador ha ido all in en la mano.
all_in:
• hole_cards: cartas del jugador en formato texto.
hole_cards:
• card_order1: ranking de la primera carta de mano
card_order1: mano en relació
relaciónn a su fuerza
individual (2->2,...,
(2 As->14).
• card_order2: ranking de la segunda carta de mano en relació
card_order2: relaciónn a su fuerza
individual (2->2,...,
(2 ..., As->14).
As
• card_order3: 1 si son suited,
card_order3: suited 0 si no.
• connector_hand: 1 si están conectadas, 0 si no.
connector_hand:
• pair_h
pair_hand: : 1 si es una pareja de mano, 0 si no.
• won_hand: 1 si el jugador ganó la mano, 0 si no.
won_hand:
• session_id: identificador de la sesión en la que se circunscribe la mano.
session_id:
• off_the_button: número de posiciones de diferencia con el button.
off_the_button:
• number_of_players: número de jugadores en la mano.
number_of_players:
• big_blind_n: 1 si es big blind,
big_blind_n: blind 0 si no.
• small_blind_n: 1 si es small blind,
small_blind_n: blind, 0 si no.
• went_to_showdown_n: 1 si llegó con la mano hasta el final, 0 si no.
went_to_showdown_n:
• saw_flop_n: 1 si vió el flop,, 0 si no.
saw_flop_n:
• attempted_steal: 1 si intentó un robo,
attempted_steal: robo 0 si no.
• raised_first_pf: 1 si subió el primero antes del flop,, 0 si no.
raised_first_pf:
• real_player_id: identificador real del jugador (no su alias).
real_player_id:
• chip_count stack con el que el jugador comenzó la mano.
chip_count:
• blind_ _amt:: cantidad de fichas pagadas en la mano en concepto de ciegas (0 si
el jugador está fuera de las posiciones que pagan ciegas).
• ante_amt: cantidad de fichas pagadas en concepto de anteante.
Hay muchos otros campos booleanos (valores cierto o falso, 0 ó 1) que definen cada
una de las posibles acciones que el jugador
jugador ha podido realizar en cada una de las calles
(call,, check-raise raise,, etc.) y que servirán para mostrar las estadísticas en las
raise, bet-raise
ventanas del PT. Esta tabla es similar a la anterior pero orientada a torneos (por eso
algunas columnas diferentes como como la de los antes).).
♠ Tabla tourney..
Define los datos generales de los torneos. Cada fila identifica un solo torneo importado
en PT. Contiene los campos siguientes:
Spainfull - Póquer
óquer yo lo valgo Page 17
• tourney_end:: fecha y hora de fin del torneo.
tourney_end
• buy_in: dinero que costó la entrada al torneo.
buy_in:
• fee:: dinero
dinero pagado como comisión a la sala de póquer.
• tourney_type: tipo de torneo (si no concreto más es porque no tengo apenas
tourney_type:
torneos guardados en la base de datos y no tengo ni puta idea de cuáles son los
valores).
• table_type: tipo de mesa (ídem. a la anterior).
table_type: anterior)
• summary_text: resumen en formato texto del identificador del torneo.
summary_text:
• target_tourney_number: si es un satélite, indica el identificador del
target_tourney_number:
torneo en la sala al que se opta si se consigue una plaza.
• number_of_players: número de jugadores del torneo.
number_of_players:
• tourney_notes: notas del torneo.
tourney_notes:
• summary_loaded: si se ha importado en el PT el resumen del torneo.
summary_loaded:
♠ Tabla session.
Define los datos de una sesión de juego
juego (desde que te sientas a una mesa hasta que te
levantas). Contiene los campos siguientes:
Spainfull - Póquer
óquer yo lo valgo Page 18
• real_player_id:: identificador del jugador (distinto del anterior si usa alias
real_player_id
y no es la sala primera en la que PT definió al jugador).
• tot_players: número total de jugadores en el conjunto de la sesión (suma
tot_players:
los totales en cada mano, sin importar que sea el mismo jugador; es decir, si
juegas una sesión maratoniana de 2 manos contra los mismos 9 tíos, este campo
valdrá 20).
• tot_saw_flop: número total de jugadores que han visto el flop en la sesión
tot_saw_flop:
(mismo comentario que en el campo anterior).
• tot_pot: cantidad total de dinero en todos los botes de la sesión (la suma de
tot_pot:
todos los botes generados sin importar quién los ganara).
♠ Tabla tourney_summary.
tourney_summary
Define datos de los torneos desde el punto de vista de un jugador. Un torneo tendrá en
esta tabla tantas filas como jugadores hayan participado (siempre que se hayan
importado los datos a PT). Contiene los campos siguientes:
♠ Tabla player_winnings.
player_winnings
Define los datos de ganancias entre los jugadores de cash.. Cada fila identifica el dinero
que le ha ganado un jugador a otro durante una sesión. Contiene los campos siguientes:
Spainfull - Póquer
óquer yo lo valgo Page 19
• times_beat:: veces que player_id ha ganado a opponent_id en la sesión.
times_beat
• real_player_id: identificador del jugador ganador (por si usa alias).
real_player_id:
Esta tabla sirve como base para mostrar la información de ganancias y pérdidas entre
jugadores que tantas veces hemos tenido que volver a mirar varias veces por parecer
increíble que ese jugador, con lo malo que es, nos haya ganado tanto dinero.
♣ Tablas de configuración:
Almacenan los datos de configuración del PT. En este apartado se encuentran las
siguientes tablas (no merece la pena extenderse en ellas):
• dst:: rangos de fechas que utilizará para cálculos internos del programa.
• datawindow_prefs: preferencias del programa.
datawindow_prefs:
• exrates: tipo de cambio entre dólares, euros y libras que va a utilizar en los
exrates:
cálculos.
• error_msgs: mensajes de error del programa.
error_msgs:
• version_info: número de versión del programa.
Con esto concluyo la revisión pormenorizada de las tablas de PT. Espero que aclare
algunas dudas y facilite la creación de consultas que abordaré en la siguiente entrada.
Spainfull - Póquer
óquer yo lo valgo Page 20
Parte III. Tutorial para crear consultas SQL
Si no has estado despistado, sabrás que el lenguaje con el que se hacen las consultas se
llama SQL. No es más que una serie de instrucciones que sabe interpretar el motor de la
base de datos y que se emplea para manipular la información contenida en ella. En este
breve tutorial voy a centrarme exclusivamente en las órdenes de consulta, es decir, en la
recuperación de datos.
Hay una serie de palabras que conforman el lenguaje SQL y que equivalen a
instrucciones sobre la base de datos. Para hacer una consulta, se utiliza la palabra
SELECT (del inglés, seleccionar). La estructura de una consulta SQL es la siguiente:
Con un ejemplo sencillo se verá todo más claro. Poco a poco iré explicando detalles
más complicados.
SELECT *
FROM game_level
Como se ve, solo aparecen los campos seleccionados en la parte de selección. Cabe
destacar, que si no se usa la parte de condición, la selección se hace sobre todas las filas
de la tabla. El número de columnas de la tabla resultado es el número de elementos que
tenemos en la selección separados por comas; en este caso, dos. El título de la columna
de la tabla resultado es el del nombre del campo.
En la parte de selección se pueden utilizar una serie de funciones que hacen operaciones
sobre los campos, se escribe la palabra que representa a la función y entre paréntesis el
campo al que se le aplica. Las funciones son:
SELECT MAX(pot)
FROM game
Si ahora se quiere obtener el bote máximo ganado por cada jugador, se puede
utilizar una nueva instrucción que agrupa las filas que tienen el mismo valor en
un campo. Esa instrucción se representa en SQL mediante las palabras GROUP
BY. Para hacer esta consulta, habrá que agrupar las filas que tengan el mismo
valor en el campo player_id (que es el que identifica al jugador). Para que
aparezca también el identificador del jugador, se añade ese campo en la
selección:
Ahora voy a tratar la parte condicional de las consultas. Hasta aquí, las
consultas estaban realizadas sobre todas las filas de la tabla. Si se quiere
seleccionar sobre solo una fracción de ellas, es preciso usar la parte del WHERE.
A continuación es preciso establecer las condiciones que debe cumplir la
búsqueda. Para ello se usan los campos o los alias (entre corchetes) de la parte
de la selección y las relaciones entre ellos. Estas relaciones pueden ser de
comparación: mayor que, menor que, mayor o igual que, menor o igual que,
distinto, igual (>, <, >=, <=, <>, =); lógicas: y, o, no (And, Or, Not) y otros
operadores como intervalo (Between And), filas diferentes (Distinct),
similares (Like), conjunto (In, Not In), si el campo es vacío (Is Null), etc.
Para entenderlo mejor, voy a hacer la consulta del máximo bote de cash menor
de 50:
Se suman todos los botes y se divide por el número de filas en las que he ganado
(en el campo player_id de la tabla game se almacena el ganador de la mano).
Si además se desea saber el bote medio obtenido en un nivel concreto (los
niveles se guardan en la tabla game_level), por ejemplo en $1/$2 que
corresponde con identificador 5 (game_level_id establece el nivel de la mano
en la tabla game):
SELECT SUM(pot)/COUNT(game_id) AS bote_medio
FROM game
WHERE player_id = 1 AND game_level_id = 5
Si además se quiere ver el total y el número de botes ganados para que quede
más informativa y clara la consulta:
Para obtener datos que se encuentran en más de una tabla que están unidos por
un identificador (como por ejemplo player_id en varias tablas) hay que
utilizar lo que se conoce como unión. Por ejemplo, si en la consulta realizada
anteriormente del bote máximo de cada jugador se quieren obtener más datos
por jugador, hay que mirar en la tabla players. Si por ejemplo se quiere
mostrar además el nombre del jugador al que pertenece ese identificador, habrá
que obtenerlo de esa tabla. Para conseguirlo, en la parte de selección se señala
de qué tabla proviene cada campo anteponiendo al nombre del campo el
nombre de la tabla a la que pertenece y un punto. En la parte de origen, se
ponen los nombres de las tablas separados por la instrucción INNER JOIN y se
especifica qué campos son los que unen las tablas (los que significan lo mismo,
son del mismo tipo aunque puedan tener distinto nombre) tras la palabra ON:
Esta consulta se podría poner de otra manera en la que se ve claro lo que hace el
INNER JOIN:
Por último, voy a diseccionar la consulta que mostré como ejemplo en el primer artículo,
que calculaba las veces que mejoraba nuestra pareja a trío en el flop:
Antes de empezar a hacer una consulta se debe tener claro qué es lo que se quiere
conseguir y dónde están esos datos. Lo que se pretende es ver cuándo nuestra pareja de
mano ha mejorado a trío. Las cartas comunes de cada mano se guardan en la tabla game,
pero las cartas de cada jugador en cada mano se almacenan en la tabla
game_players. Por lo tanto, está claro que habrá que usar estas dos tablas. El campo
que une estas dos tablas es el game_id, que identifica unívocamente cada mano. Así,
tenemos la parte de origen que queda de la siguiente manera:
Se emplea un alias para cada tabla para no tener que volver a escribir el nombre de las
Los dos primeros elementos están claros, la mano inicial (que serán parejas por las
condiciones que se pondrán después) y el número de veces que nos han repartido esas
parejas cuando hemos visto el flop (también significará esto por las condiciones de la
parte WHERE que se añadirán). La tercera columna es más sencilla de lo que parece;
para que nuestra pareja se convierta en trío, precisa que una de las cartas del flop sea
igual a cualquiera de las que tenemos en mano; eso es lo que indica la expresión que
está dentro del SUM.
Las cartas que nos han repartido están en la tabla game_players en los campos
hole_card_1 y hole_card_2 y las del flop en la tabla game en los campos
flop_1, flop_2 y flop_3. Estos campos son alfanuméricos (letras y números) y
cada carta se representa por su valor (un número del 2 al 9 o una letra mayúscula si es
un A, T, J, Q o K seguido de una letra minúscula que indica el palo); por tanto se debe
obtener el valor de la carta sin importar el palo, es decir, el primer carácter de los
campos a seleccionar. Para ello se cuenta con la instrucción de SQL left(campo, x)
que obtiene x caracteres empezando por la izquierda en un campo alfanumérico. En este
caso nos interesa mirar si el valor de una de nuestras cartas de mano (como es una
pareja no importa con cuál comparemos) es igual a cualquiera de las tres del flop. Con
este objetivo se utiliza left(gp.hole_card_1, 1) para nuestra mano y se compara
con left(g.flop_x,1). IIF evalúa una condición y si se cumple se da el primer
valor, y si no el segundo: IIF(condición, valor_1, valor_2); en este caso, si coincide la
comparación que se hace entre nuestra carta de mano y la primera del flop, el valor es
uno y se suma y se sale de la expresión (como vez que conseguimos trío, se suma
porque se emplea SUM encerrando a la expresión completa), si no coincide se mira la
segunda del flop, si coincide se suma y se sale de la expresión, si no se mira la tercera y
si coincide se suma y se sale de la expresión, y por fin, si no es que no se consiguió trío
y el valor que se obtiene y se suma es 0. Puede parecer complicado, pero con un poco de
La primera condición es que sea nuestro jugador. Se podría poner el número que se ha
obtenido en una de las consultas anteriores, pero en este caso se ha anidado otra
consulta (se debe escribir entre paréntesis) que coge de la tabla de preferencias prefs
nuestro identificador de jugador, almacenado en el campo pref_value y que se
asocia al valor "RP" del campo pref_key. La siguiente condición es que sea una
pareja de mano, aspecto almacenado en la tabla game_players en el campo pair
(1 si es pareja de mano, 0 si no). La siguiente, que yo haya visto el flop, guardado en el
campo saw_flop de la misma tabla (1 si se ve el flop, 0 si no). Por último, se agrupan
las cartas de mano que sean iguales y también por el valor de la mano. Para mostrarlas
ordenadas por el valor de la mano se emplea la instrucción ORDER BY (y para
seleccionar que en orden inverso de valor la instrucción DESC -el valor de las cartas en
el campo card_orderx va del 2 para el 2 al 14 para el As-).
Con esto se acaba el tutorial de cómo realizar consultas SQL en la BD de PT. Espero
que te haya servido de algo. Hay mucha información disponible sobre SQL en la red
que cubre aspectos y funcionalidades que no he tratado y que pueden resultar
interesantes. De todas maneras, si tienes alguna duda, ¡pregunta coño!
HTTP://SPAINFULL.BLOGSPOT.COM/