🔍 DbQuery Builder — API fluida para queries SQL
Actualizado: 2024-12-01
DbQuery es un constructor de queries SQL de tipo fluent que PrestaShop proporciona como alternativa segura a la concatenacion de strings. Siempre genera el SQL a traves de build() y se ejecuta con Db::getInstance().
#Metodos del DbQuery Builder
| Metodo | SQL generado | Descripcion |
|---|---|---|
| select('p.id_product, pl.name') | SELECT p.id_product, pl.name | Campos a seleccionar |
| from('product', 'p') | FROM ps_product p | Tabla principal (con prefijo automatico) |
| join('JOIN ps_category c...') | JOIN ... | JOIN literal (con prefijo manual) |
| leftJoin('table', 'alias', 'on') | LEFT JOIN ps_table alias ON ... | LEFT JOIN con prefijo automatico |
| innerJoin('table', 'alias', 'on') | INNER JOIN ps_table alias ON ... | INNER JOIN |
| where('p.active = 1') | WHERE p.active = 1 | Condicion (se combinan con AND) |
| having('cnt > 5') | HAVING cnt > 5 | Condicion HAVING |
| orderBy('p.date_add DESC') | ORDER BY p.date_add DESC | Ordenacion |
| groupBy('p.id_category') | GROUP BY p.id_category | Agrupacion |
| limit(20, 0) | LIMIT 20 OFFSET 0 | Paginacion (limit, offset) |
| build() | SQL string | Genera el SQL final como string |
#Queries con JOIN
Queries complejas con multiples JOINs
php
<?php
// ── Query compleja con multiples joins ──
$query = (new DbQuery())
->select('p.id_product, pl.name, p.price, cl.name AS category_name,
m.name AS manufacturer_name, p.quantity')
->from('product', 'p')
->leftJoin(
'product_lang', 'pl',
'p.id_product = pl.id_product AND pl.id_lang = ' . (int) $idLang
. ' AND pl.id_shop = ' . (int) $idShop
)
->leftJoin(
'category_lang', 'cl',
'p.id_category_default = cl.id_category AND cl.id_lang = ' . (int) $idLang
)
->leftJoin(
'manufacturer', 'm',
'p.id_manufacturer = m.id_manufacturer'
)
->innerJoin(
'stock_available', 'sa',
'p.id_product = sa.id_product AND sa.id_product_attribute = 0'
)
->where('p.active = 1')
->where('p.visibility IN (\'both\', \'catalog\')')
->orderBy('p.date_add DESC')
->limit(20, ($page - 1) * 20); // Paginacion
$products = Db::getInstance()->executeS($query);
#Filtros WHERE y HAVING
Construccion dinamica de condiciones WHERE
php
<?php
$query = (new DbQuery())
->select('p.id_product, pl.name, p.price')
->from('product', 'p')
->leftJoin('product_lang', 'pl',
'p.id_product = pl.id_product AND pl.id_lang = ' . (int) $idLang
);
// ── Condiciones dinamicas ──
if ($activeOnly) {
$query->where('p.active = 1');
}
if ($minPrice > 0) {
$query->where('p.price >= ' . (float) $minPrice);
}
if ($maxPrice > 0) {
$query->where('p.price <= ' . (float) $maxPrice);
}
if ($searchTerm) {
$term = pSQL($searchTerm);
$query->where("pl.name LIKE '%" . $term . "%'");
}
if ($idCategory) {
$query->where('p.id_category_default = ' . (int) $idCategory);
}
// ── HAVING para campos calculados ──
$query
->select('COUNT(o.id_order) AS total_orders')
->leftJoin('orders', 'o', 'p.id_product = o.id_product')
->groupBy('p.id_product')
->having('total_orders > 5');
$results = Db::getInstance()->executeS($query);
#Paginacion y ordenacion
Paginacion con DbQuery
php
<?php
$page = max(1, (int) Tools::getValue('page', 1));
$perPage = 20;
$offset = ($page - 1) * $perPage;
// ── Query paginada ──
$query = (new DbQuery())
->select('p.id_product, pl.name, p.price')
->from('product', 'p')
->leftJoin('product_lang', 'pl',
'p.id_product = pl.id_product AND pl.id_lang = ' . (int) $idLang
)
->where('p.active = 1')
->orderBy('p.date_add DESC')
->limit($perPage, $offset);
$products = Db::getInstance()->executeS($query);
// ── Contar el total sin LIMIT ──
$countQuery = (new DbQuery())
->select('COUNT(p.id_product) AS total')
->from('product', 'p')
->where('p.active = 1');
$total = (int) Db::getInstance()->getValue($countQuery);
$totalPages = ceil($total / $perPage);
#Subqueries
Subqueries con DbQuery
php
<?php
// ── Subquery en WHERE con IN ──
$categoryIds = [1, 3, 7, 12];
$query = (new DbQuery())
->select('*')
->from('product', 'p')
->where('p.id_category_default IN (' . implode(',', array_map('intval', $categoryIds)) . ')');
// ── Subquery como tabla ──
$subQuery = (new DbQuery())
->select('id_order, MAX(date_add) AS last_date')
->from('order_history')
->groupBy('id_order');
$mainQuery = (new DbQuery())
->select('o.id_order, o.reference, oh_last.last_date')
->from('orders', 'o')
->join('INNER JOIN (' . $subQuery->build() . ') oh_last ON o.id_order = oh_last.id_order')
->where('o.valid = 1');
$results = Db::getInstance()->executeS($mainQuery);
#Ejecutar la query
Metodos de Db:: para ejecutar queries
php
<?php
$db = Db::getInstance();
// ── Multiples filas → array de arrays asociativos ──
$rows = $db->executeS($query); // Devuelve array o false
$rows = $db->executeS($query) ?: []; // Devuelve array vacio si no hay resultados
// ── Una sola fila → array asociativo ──
$row = $db->getRow($query);
if ($row) {
echo $row['name'];
}
// ── Un solo valor ──
$count = (int) $db->getValue($query);
$name = (string) $db->getValue($query);
// ── Obtener el SQL generado para debug ──
$sql = $query->build();
echo $sql;
// ── Debug en modo dev ──
if (_PS_MODE_DEV_) {
PrestaShopLogger::addLog('SQL: ' . $query->build(), 1);
}
Descargar en Markdown
Pensado para pegar en ChatGPT, Claude u otra IA. Incluye solo el contenido de esta pagina.