2012-04-29 3 views
4

Как часть более крупного запроса с динамически сгенерированными элементами, мне нужно сделать левое соединение и подсчитать. Это необходимый мне запрос.Литиевое число с левым соединением

SELECT slug, name, count(client_tests.id) AS test_count 
    FROM clients 
    LEFT JOIN client_tests ON clients.id = client_tests.client_id 
    GROUP BY clients.id; 

Я пытался построить присоединиться запрос, но литий-видимому, ожидать объединения быть частью отношений (никаких отношений не определены), как показано ниже (не обращая внимания на количество на данный момент).

$join = new Query(array(
    'source' => 'client_tests', 
    'model' => '\app\models\ClientTest', 
    'type' => 'LEFT', 
    'constraint' => array('Client.id' => 'ClientTest.client_id'), 
)); 
$clients = Client::all(array(
    'conditions' => $conditions, 
    'group' => 'Client.id', 
    'joins' => array($join) 
)); 

Это приводит к Notice: Undefined index: ClientTest in /usr/local/www/oars/libraries/lithium/data/collection/RecordSet.php on line 340, который, как представляется, код отношения, связанные с.

Если я определяю отношения между клиентом и ClientTest, который будет обрабатывать построение левого соединения для меня, есть ли способ получить поля клиента и счетчик?

$clients = Client::all(array(
    'fields' => array('slug', 'name', 'count(ClientTest.test_id) as test_count'), 
    'conditions' => $conditions, 
    'group' => 'Client.id', 
    'with' => 'ClientTest' 
)); 

Это приводит к (!) Notice: Undefined index: count(ClientTest in /usr/local/www/oars/libraries/lithium/data/source/Database.php on line 650, так как это не возможно, или я использую неправильный синтаксис.

Я мог бы просто выдать запрос напрямую с помощью Client::connection()->read($sql), но поскольку в запрос есть динамические элементы, мне все равно придется строить SQL.

Есть ли способ заставить эти методы работать, или мне нужно вручную создать SQL?

ответ

0

Должен признаться, что я не знаком с литием. Тем не менее, есть два способа приблизиться к этому в SQL, который вы также можете попробовать.

Я предполагаю, что вы пытаетесь получить общее количество строк, возвращаемых в качестве дополнительного столбца в каждой строке.

Для первого требуется что-то, называемое оконными функциями (также известными как аналитические функции в Oracle). Запрос будет выглядеть так:

SELECT *, count(*) over (partition by clients.id) AS test_count 
FROM clients LEFT JOIN client_tests 
    ON clients.id = client_tests.client_id 

Второй подход используется в базах данных, которые не поддерживают это. Для обработки одного запроса необходимо выполнить следующие работы:

with q as (SELECT c.*, <whatever columns you want from client_tests 
      FROM clients LEFT JOIN 
       client_tests 
       ON clients.id = client_tests.client_id 
     ) 
select q.*, qsum.test_count 
from q join 
    (select id, count(*) as test_count 
     from q 
     group by id 
    ) qsum 
    on q.id = qsum.id 

Возможно, один из них будет работать в вашем случае.

+0

Написание запроса не является проблемой, лучший способ заставить его работать в литии - это именно тот вопрос, который я задал. – michaeltwofish

+0

Ваш исходный запрос не имеет смысла как SQL. Он имеет «select *» с группой. Если вы начнете с правильного SQL-запроса, возможно, остальные будут падать на место. –

+0

Я ценю вашу помощь, и я был неаккуратен с SQL, но запрос не является проблемой. В этом вопросе можно проиллюстрировать то, что я хочу в итоге, но он не используется в качестве входных данных нигде. – michaeltwofish

0

Ваш запрос кажется странным. Попробуйте это:

SELECT slug, name, count(client_tests.id) AS test_count 
FROM clients 
LEFT JOIN client_tests ON clients.id = client_tests.client_id 
GROUP BY clients.id; 
+0

Запрос не является проблемой. – michaeltwofish

1

Если я правильно вас понимание у вас уже есть запрос SQL, который возвращает набор результатов, что вы ищете, но возникают проблемы с литием. Я бы предложил попробовать это. Если вы создадите представление запроса, который вам нужен в SQL, вы можете лишить его простой запрос к представлению. У меня нет абсолютно никакого опыта с литием, но я надеюсь, что это поможет. Удачи.

0

Похоже, вы просто missTyped свое имя таблицы,

'constraint' => array('Client.id' => 'ClientTest.client_id') 

Но у вас есть:

LEFT JOIN client_tests ON clients.id = client_tests.client_id 

Вы только что совершили ошибку между client_tests и ClientTest?

+0

Нет, литиевые псевдонимы таблицы автоматически. – michaeltwofish

Смежные вопросы