左连接的锂计数

时间:2012-04-29 06:53:30

标签: sql lithium

作为使用动态生成元素的大型查询的一部分,我需要进行左连接和计数。这是我需要的查询。

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;

我试图构建一个连接查询,但是Lithium似乎期望连接成为关系的一部分(没有定义任何关系),如下所示(忽略现在的计数)。

$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,这似乎是与关系相关的代码。

如果我在Client和ClientTest之间定义hasMany关系,它将处理为我构建左连接,有没有办法获取客户端字段和计数?

$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?

4 个答案:

答案 0 :(得分:1)

如果我正确理解你,你已经有了SQL查询,它返回了你正在寻找的结果集,但却遇到了锂电池的麻烦。我建议尝试这个。 如果您在SQL中创建了所需查询的视图,则可以让锂向视图发送一个简单的请求。我绝对没有锂的经验,但我希望有所帮助。祝你好运。

答案 1 :(得分: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

也许其中一个适用于您的情况。

答案 2 :(得分: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;

答案 3 :(得分:0)

好像你只是想念你的表名,

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

但你有:

LEFT JOIN client_tests ON clients.id = client_tests.client_id

你刚刚在client_tests和ClientTest之间犯了错误吗?