#php #kohana
#php #kohana
Вопрос:
Мне нужно создать запрос типа (я использую PostgreSQL):
(SELECT * FROM t1 WHERE a>b ORDER BY a DESC)
UNION ALL
(SELECT * FROM t1 WHERE a<b ORDER BY a DESC)
Итак, я пытаюсь использовать конструктор запросов
$query1 = DB::select('*')
->from('t1')->where('a', '>', 'b')->order_by('a', 'desc');
$query2 = DB::select('*')
->from('t1')->where('a', '<', 'b')->order_by('a', 'desc');
$result = $query1->union($query2, TRUE);
Но в результате у меня есть sql-запрос, где выбирается без скобок. Вот так:
SELECT * FROM t1 WHERE a>b ORDER BY a DESC
UNION ALL
SELECT * FROM t1 WHERE a<b ORDER BY a DESC
И получите синтаксическую ошибку SQL… Извините за мой английский
Ответ №1:
Почему бы и нет SELECT * FROM t1 WHERE a != b ORDER BY a DESC
?
Редактировать
Для более сложного запроса, когда вам действительно нужно два или более ПОРЯДКА, я вижу только это решение:
$query1 = DB::select()
->from('t1')
->where('a', '>', 'b')
->order_by('a', 'DESC')
->__toString();
$query2 = DB::select()
->from('t1')
->where('a', '<', 'b')
->order_by('a', 'DESC')
->__toString();
$query3 = '(' . $query1 . ') UNION ALL (' . $query2 . ')';
$result = DB::query(Database::SELECT, $query3)->execute();
Комментарии:
1. У меня более сложный запрос. Здесь я описываю проблему. И я хочу найти проблему, как заключить мой запрос в скобки.
2. В общем, я должен отобразить список голосов. Сначала те, за которые пользователь не проголосовал, и после всех оставшихся голосов упорядочиваются по дате
3. Краткое примечание: вам не нужно вызывать
__toString()
; это делается автоматически, когда вы объединяете запросы в $query34. да, это работает для меня! Спасибо. Но я изменил Database_Query_Builder_Select-> compile и добавил в них скобки. Это тоже работает.
Ответ №2:
Другой способ решить эту проблему — изменить class Database_Query_Builder_Select
. Таким образом, создайте запрос объединения со скобками, например: (select_1) union (select_2) union (select_n)
. И вы можете использовать ORDER BY
and LIMIT
в каждом SELECT
операторе
1) Создайте папку application/classes/database/query/builder/
2) Создайте файл select.php
3) Вставьте в созданный файл этот код:
<?php defined('SYSPATH') or die('No direct script access.');
class Database_Query_Builder_Select extends Kohana_Database_Query_Builder_Select {
protected $_union_limit = NULL;
/**
* Insert LIMIT statement after all unions
*
* @param integer $number
*/
public function union_limit($number)
{
$this->_union_limit = (int) $number;
return $this;
}
/**
* Compile the SQL query and return it.
*
* @param object Database instance
* @return string
*/
public function compile(Database $db)
{
// Callback to quote columns
$quote_column = array($db, 'quote_column');
// Callback to quote tables
$quote_table = array($db, 'quote_table');
// Start a selection query
$query = 'SELECT ';
if ( ! empty($this->_union)) $query = DB::expr('(SELECT ');
if ($this->_distinct === TRUE)
{
// Select only unique results
$query .= 'DISTINCT ';
}
if (empty($this->_select))
{
// Select all columns
$query .= '*';
}
else
{
// Select all columns
$query .= implode(', ', array_unique(array_map($quote_column, $this->_select)));
}
if ( ! empty($this->_from))
{
// Set tables to select from
$query .= ' FROM '.implode(', ', array_unique(array_map($quote_table, $this->_from)));
}
if ( ! empty($this->_join))
{
// Add tables to join
$query .= ' '.$this->_compile_join($db, $this->_join);
}
if ( ! empty($this->_where))
{
// Add selection conditions
$query .= ' WHERE '.$this->_compile_conditions($db, $this->_where);
}
if ( ! empty($this->_group_by))
{
// Add sorting
$query .= ' GROUP BY '.implode(', ', array_map($quote_column, $this->_group_by));
}
if ( ! empty($this->_having))
{
// Add filtering conditions
$query .= ' HAVING '.$this->_compile_conditions($db, $this->_having);
}
if ( ! empty($this->_order_by))
{
// Add sorting
$query .= ' '.$this->_compile_order_by($db, $this->_order_by);
}
if ($this->_limit !== NULL)
{
// Add limiting
$query .= ' LIMIT '.$this->_limit;
}
if ($this->_offset !== NULL)
{
// Add offsets
$query .= ' OFFSET '.$this->_offset;
}
if ( ! empty($this->_union))
{
$iteration = 1;
foreach ($this->_union as $u) {
if ($iteration == 1) $query .= ')';
$query .= ' UNION ';
if ($u['all'] === TRUE)
{
$query .= 'ALL ';
}
$query .= '('.$u['select']->compile($db).')';
$iteration ;
}
}
if ( ! empty($this->_union_limit))
{
$query .= ' LIMIT '.$this->_union_limit;
}
$this->_sql = $query;
return $query;
}
}