Writing this SQL in Kohana query builder - sql

SELECT users.*
FROM users INNER JOIN roles_users ON users.id = roles_users.user_id
WHERE roles_users.role_id IN (1, 2)
GROUP BY users.id
HAVING COUNT(*) = 2
I came this far:
DB::select()->from('users')->join('roles_users')
->on('users.id', '=', 'roles_users.user_id')
->where('roles_users.role_id', 'IN', array(1, 2))
How can i do GROUP BY and HAVING COUNT(*) in Kohana query builder?

Why don't you do it like this?
$query = DB::query(Database::SELECT,
'SELECT users.*
FROM users INNER JOIN roles_users ON users.id = roles_users.user_id
WHERE roles_users.role_id IN (1, 2)
GROUP BY users.id
HAVING COUNT(*) = 2'
);
$query->execute();
Example:
$results = DB::query(Database::SELECT,
'SELECT * FROM
post_scheduled
WHERE
DATE(FROM_UNIXTIME(scheduled)) = DATE(NOW())
AND
TIME_FORMAT(FROM_UNIXTIME(scheduled), "%H:%i") = TIME_FORMAT(NOW(), "%H:%i")
AND
published = 0'
)->execute()->as_array();
foreach($results as $result)
{
$id = $result['id'];
# ...
}
Query builder... (haven't tested)
DB::select()
->from('users')
->join('roles_users')
->on('users.id', '=', 'roles_users.user_id')
->where('roles_users.role_id', 'IN', array(1, 2))
->group_by('users.id')
->having('COUNT(*)', '=', '2');

Related

Eloquent select with join and not exists in raw statement

I need to write select statement like that:
SELECT co.id FROM client_order co
INNER JOIN client_order_status cos ON cos.id = co.order_status_id AND cos.name IN ('for_shipping', 'to_be_shipped_later')
WHERE NOT EXISTS (SELECT 1 FROM dpackage dp WHERE dp.order_id = co.id AND dp.is_spec_label_generated = 1)
ORDER BY co.id
In Eloquent my expression looks like that:
$clientOrderEntities = ClientOrder::join('client_order_status', 'client_order_status.id', '=', 'order_status_id')
->whereIn('client_order_status.name', ['for_shipping', 'to_be_shipped_later'])
->whereNotExists(function($query) use($orderId) {
$query->select(DB::raw(1))
->from('dpackage')
->where([
['order_id', '=', $orderId]
['is_spec_label_generated', '=', 1]
]);
})->get();
I don't know how to pass orderId from first part of query into whereNotExists sub query
At the moment it looks:
$clientOrderEntities = ClientOrder::join('client_order_status', 'client_order_status.id', '=', 'order_status_id')
->whereIn('client_order_status.name', ['for_shipping', 'to_be_shipped_later'])
->whereNotExists(function($query) {
$query->select(DB::raw(1))
->from('dpackage')
->where([
['order_id', '=', 'client_order.id'],
['is_spec_label_generated', '=', 1]
]);
})
->select('client_order.*')
->get();
This query works:
$clientOrderEntities = ClientOrder::join('client_order_status', 'client_order_status.id', '=', 'order_status_id')
->whereIn('client_order_status.name', ['for_shipping', 'to_be_shipped_later'])
->whereRaw(' NOT EXISTS (SELECT 1 FROM dpackage dp WHERE dp.order_id = client_order.id AND dp.is_spec_label_generated = 1) ')
->select('client_order.*')
->get();
This query works too and is faster than eloquent statements, as #Newbie wrotes, but I don't know why his answer has been deleted:
$clientOrderEntities = DB::select('SELECT co.* FROM client_order co INNER JOIN client_order_status cos ON cos.id = co.order_status_id AND cos.name IN ("for_shipping", "to_be_shipped_later") WHERE NOT EXISTS (SELECT 1 FROM dpackage dp WHERE dp.order_id = co.id AND dp.is_spec_label_generated = 1) ');
Maybe defining name for the tables help you with this.
$clientOrderEntities = \DB::table('client_order as co')
->join('client_order_status as cos', 'cos.id', '=', 'co.order_status_id')
->whereIn('cos.name', ['for_shipping', 'to_be_shipped_later'])
->whereNotExists(function($query) {
$query->select(DB::raw(1))
->from('dpackage')
->where([
['order_id', '=', 'co.id'],
['is_spec_label_generated', '=', 1]
]);
})->get();

Two queries return different data

I am running two queries according to me both should return same result, but i think i am missing something
SELECT "id", "email", "first_name", "last_name", locale
FROM "users" AS "users"
WHERE (
EXISTS (
SELECT cf.field_value, ucf.field_value
FROM custom_fields cf
LEFT JOIN users_custom_fields ucf ON cf."id" = ucf.custom_field_id
WHERE cf."id" = 272 AND
((
cf.field_value = 'true') OR
(
ucf.user_id = users.id AND ucf.field_value = 'true'))
))
it returns record
SELECT users.id, cf.field_value, ucf.field_value, ucf.user_id
FROM users
Join custom_fields cf on cf.user_id = users.id
LEFT join users_custom_fields ucf on ucf.custom_field_id = cf."id"
WHERE cf."id" = 272 AND
((
cf.field_value = 'true') OR
(ucf.user_id = users.id AND ucf.field_value = 'true'))
and it doesn't return anything, is there any difference between these two?
your second query you also join custom_fields table with cf.user_id = users.id. first query does not have this.
With adding cf.user_id = users.id, your first query equal the second.
SELECT "id", "email", "first_name", "last_name", locale FROM "users" AS "users" WHERE (
EXISTS (
SELECT cf.field_value, ucf.field_value
FROM custom_fields cf
LEFT JOIN users_custom_fields ucf ON cf."id" = ucf.custom_field_id
WHERE cf."id" = 272
AND cf.user_id = users.id
AND (( cf.field_value = 'true') OR
( ucf.user_id = users.id AND ucf.field_value = 'true'))
))

Query with select and count in laravel

I did this Query in SQL but I can't make it work in Eloquent.
Please help me.
SELECT
tags.desc,
COUNT(planificacion_info.id_area) as cantidad_intervenciones
FROM
tags
INNER JOIN planificacion_info ON planificacion_info.id_area = tags.id_tag
WHERE
tags.grupo = 'area' and tags.estado = true
GROUP BY
tags.desc
You can do it like this :
$result = \DB::table('tags')->selectRaw('tags.desc, COUNT(planificacion_info.id_area) as cantidad_intervenciones')
->join('planificacion_info', 'planificacion_info.id_area', '=', 'tags.id_tag')
->where('tags.grupo', 'area')
->whereRaw('tags.estado = true')
->groupBy('tags.desc')
->get();
which gives you this request :
SELECT
tags.desc,
COUNT(planificacion_info.id_area) AS cantidad_intervenciones
FROM
`tags`
INNER JOIN `planificacion_info` ON `planificacion_info`.`id_area` = `tags`.`id_tag`
WHERE
`tags`.`grupo` = 'area'
AND tags.estado = TRUE
GROUP BY
`tags`.`desc`
Would be something liek this
$tags= DB::table('tags')
->select('tags.desc',DB::raw("COUNT(planificacion_info.id_area) AS cantidad_intervenciones")
->innerJoin('planificacion_info','planificacion_info.id_area','=','tags.id_tag')
->where('tags.grupo','area')
->where('tags.estado',true)
->groupBy('tags.desc')
->get();

Zend select object - building a query

How can I write the query below in Zend Select object notation so using ->join()->where() etc?
SELECT t.id, t.user_id, t.added_date, u.id, u.phone, bk.call_status
FROM `transaction` t
INNER JOIN
(
SELECT id, MAX(added_date) AS addedDate
FROM `transaction`
GROUP BY id
) gt
ON t.id = gt.id AND t.added_date = gt.addedDate
LEFT JOIN `user` u ON t.user_id = u.id
LEFT JOIN `bok_call` bk ON bk.user_id = t.user_id
WHERE NOT t.user_id = 'null'
AND addedDate BETWEEN '2008-05-04 17:51:48' AND '2009-05-04 17:51:48'
AND NOT u.phone = ''
AND bk.call_status IS null
For example this way:
$joinSelect = $model->select()
->from('transaction'), array('id', 'addedDate' => 'MAX(added_date)'))
->group('id');
$select = $model->select()
->setIntegrityCheck(false)
->from(array('t' => 'transaction'), array('id', 'user_id', 'added_date'))
->join(array('gt' => $joinSelect), 't.id = gr.id AND t.added_date = gt.addedDate', array());
->joinLeft(array('u' => 'user'), 't.user_id = u.id', array('id', 'phone'))
->joinLeft(array('bk' => 'bok_call'), 'bk.user_id = t.user_id', array('call_status'))
->where('t.user_id != ?', 'null')
->where("addedDate BETWEEN '2008-05-04 17:51:48' AND '2009-05-04 17:51:48')
->where('u.phone != ?', '')
->where('bk.call_status IS NULL');
Be aware that you won't be able to differentiate 't.id' and 'u.id' in result.

SQL query with multiple Joins using CodeIgniter active records

I have this working query:
$q = $this->db->query('SELECT u.name FROM users u
JOIN user_group ug ON u.id = ug.user_id
JOIN groups g ON g.id = ug.group_id WHERE ug.group_id = "4" ');
And I want to replace it with aactive record. I come up with something like this but obviously it doesn't work :
$this->db->select('name');
$this->db->from('users');
$this->db->join('user_group', 'user_group.user_id = users.id);
$this->db->join('groups', 'groups.id = user_group.group_id');
$q = $this->db->get();
Thanks
Leron
I think you forget add where clause. And there was single quote missing.
$this->db->select('name');
$this->db->from('users');
$this->db->join('user_group', 'user_group.user_id = users.id');
$this->db->join('groups', 'groups.id = user_group.group_id');
$this->db->where('user_group.group_id', 4);
$q = $this->db->get();