Advanced query with kohana ORM - kohana

If you know my tables looks like these
[category]
-category_id
-lft
-rgt
....
[catinfo]
-catinfo_id
-category_id
-lang_id
-name
....
[lang]
-lang_id
-language
How can I rewrite this query in Kohana ORM?
SELECT node.category_id, catinfo.name, COUNT("parent.category_id") - 1 AS depth
FROM category AS parent, category AS node
LEFT JOIN catinfo
ON catinfo.category_id = node.category_id
WHERE node.lft BETWEEN parent.lft AND parent.rgt
AND catinfo.lang_id = 1
GROUP BY node.category_id
HAVING depth <= 3
ORDER BY node.lft
I don't have any clue how to start with it.

Better not write such a complex query with the ORM and just use the query builder or normal queries.
The query will probably look something like this if you use the query builder:
DB::select(
'node.catergory_id',
'catinfo.name',
array(DB::expr('COUNT(`parent.category_id`) - 1'), 'depth')
)
->from(array('category', 'parent'), array('category', 'node'))
->join('catinfo', 'LEFT')
->on('catinfo.category_id', '=', 'node.category_id')
->where('node.lft', 'BETWEEN', array('parent.lft', 'parent.rgt'))
->and_where('catinfo.lang_id', '=', 1)
->group_by('node.category_id')
->having('depth', '<=', 3)
->order_by('node.lft');

Related

How to sort by sum of field of a relation on sails.js?

I searched a lot about sorting elements by sum of votes (in another model), like I do in SQL here :
SELECT item.* FROM item
LEFT JOIN (
SELECT
vote.item,
SUM(vote.value) AS vote.rating
FROM vote
GROUP BY vote.item
) AS res ON item.id = vote.item
ORDER BY res.rating DESC
Is there a way to do it via waterline methods ?
I think you can't do the left join with simple waterline methods, but you can use the .query method to execute your raw SQL syntax.
Sails MySQL adapter makes sum('field') conflict with sort('field'). It will generate SQL query like:
SELECT SUM(table.field) AS field FROM table ORDER BY table.field;
But I want:
SELECT SUM(table.field) AS field FROM table ORDER BY field;
It same as:
SELECT SUM(table.field) AS f FROM table ORDER BY f;
My solution is using lodash.sortBy() to process results. https://lodash.com/docs/4.16.4#sortBy

Sequelize with join, group by, having, order by

How this query can be written using ORM?
SELECT p.id,
p.name,
COUNT(c.id) counter
FROM Posts p
LEFT JOIN Comments c
ON c.post_id = p.id
WHERE p.rating > 100
GROUP BY p.id
HAVING counter > 10
ORDER BY counter DESC
LIMIT 5
Try this:
Post.findAll({
where: {rating: {gt: 100}},
include: [Comments],
having: ['COUNT(?) >= ?', '`comment`.`id`', 10]
})
Read my research by this question.
i use sequelize#2.0.0-dev9
Since there is aggregated column counter in your query I think there is no standard ORM method to fetch entities by this query. But Sequelize provide the way to run raw SQL expression and parse results in any model you need. Or even deeper you can parse response yourself creating as complex result as you need.
Here is related docs for this case:
http://docs.sequelizejs.com/manual/tutorial/raw-queries.html

OrmLite and Common table expressions

I'm trying to run a similar query:
sql = #"with t(id) as (select 1 )
select * from Project
where id > (select id from t)";
var projects = this.Db.Query<Project>(sql).ToArray();
For some reason the OrmLite decides to treat the sql as as "where" clause, so what ends up running is something like this:
select field1, field2 from project where with t(id) .....
Does it look for a "select" at a starting position of the query ?
Short of creating a view - is there a way to run query with CTE ?
Use the db.Sql* API's for raw SQL Queries, e.g:
var projects = db.SqlList<Project>(sql);

How to use BETWEEN clause in Kohana ORM

I am new to kohana. I am using ORM for getting data.
I want to build a query in which BETWEEN clause is there. as following
SELECT `rooms`.* FROM `rooms` LEFT JOIN `events` ON (`rooms`.`id` = `events`.`room_id`)
WHERE `events`.`room_id` IS NULL
OR (`events`.`eventstart` NOT BETWEEN 1312210800 AND 1312218000)
for that i am doing the following
$rooms = $room->join('events', 'LEFT')
->on('rooms.id', '=', 'events.room_id')
->where('events.room_id', 'IS', NULL)
->and_where_open()
->or_where('events.eventstart' , 'NOT BETWEEN', $from)
->and_where_close()
->find_all();
But i am getting the the query like this
SELECT `rooms`.* FROM `rooms` LEFT JOIN `events` ON (`rooms`.`id` = `events`.`room_id`)
WHERE `events`.`room_id` IS NULL AND (`events`.`eventstart` NOT BETWEEN 1312210800)
Can someone point out how to use BETWEEN clause
I think you should use or_where('events.eventstart', 'BETWEEN', array($from, $to));
Documentation on Kohana Query Builder can be found here -> http://kohanaframework.org/3.2/guide/database/query/builder
ORM uses Query Builder.
The only way I've found that works reliably is to use DB::expr().
Consider the following:
or_where('events.eventstart', 'NOT BETWEEN', DB::expr('1312210800 AND 1312218000'));
Or you can stick it all in variables:
$range = "{$from} AND {$to}";
or_where('events.eventstart', 'NOT BETWEEN', DB::expr($range));

subsonic join to nested selected statement

Is it possible to do a join to a nested select statement in SubSonic 2.2? I am having trouble with this because I have to do a group by...
I.E.
select conn_company.company_name, SUM(t.quote_grand_total) as 'SUM' from conn_company
inner join
(SELECT *
FROM [dbo].[QuoteDBAll]
where [dbo].[QuoteDBAll].[quote_status_id] = 1
AND [dbo].[QuoteDBAll].[quote_ca_modified_date] BETWEEN '12/1/2000' AND '12/1/2009'
) t
on conn_company.company_id = t.company_id
group by company_name
having company_name = 'JACK'
Unfortunately you're not going to be able to convert that SQL into SubSonic 2 syntax. I would suggest you create a sql view based on your query and get SubSonic to generate a model from that instead.

Resources