How to use BETWEEN clause in Kohana ORM - kohana

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));

Related

Acumatica SQL to BQL - Not In

Good day
I am trying to convert my SQL to BQL but I don't know how to do the NOT IN Statment in BQL. I used NotIn2 with search I am not sure if that is right?
I keep on getting time out issues if I use it so I can't test
SELECT INTran.*,
FROM INTran
JOIN INTranSplit ON INTran.RefNbr = INTranSplit.RefNbr
JOIN InventoryItem ON InventoryItem.InventoryID = INTran.InventoryID
WHERE INTran.LotSerialNbr NOT IN
(
SELECT LotSerialNbr
FROM SOShipLineSplit
)
AND InventoryItem.inventoryCD = 'NIS004';
I am going to use it in a foreach loop with the below:
foreach (INTran item in PXSelectJoin<
INTran,
LeftJoin<INTranSplit,
On<INTranSplit.refNbr, Equal<INTran.refNbr>>,
LeftJoin<InventoryItem,
On< INTran.inventoryID, Equal<InventoryItem.inventoryID>>>>,
Where<INTran.lotSerialNbr, NotIn2<Search<SOShipLineSplit.lotSerialNbr>>,
And<InventoryItem.inventoryCD, Equal<Required<InventoryItem.inventoryCD>>>>
>.Select(Base, "NIS004")){}
Well, you cannot implement NotIn with subselect that easily in BQL. But here is what you can do:
You can alter the select to get the same result using join:
PXSelectJoin<INTran,
InnerJoin<INTranSplit, On<...>,
InnerJoin<InventoryItem, On<...>,
LeftJoin<SOShipLineSplit, On<SOShipLineSplit.lotSerialNbr, Equal<INTran.lotSerialNbr>>>>>,
Where<InventoryItem.inventoryCD, Equal<Required<InventoryItem.inventoryCD>>,
And<SOShipLineSplit.ShipmentNbr, IsNull>>
In that example you will only select lines for which SOShipLineSplit was not found

Spark SQL query with IN operator in CASE WHEN cannot be cast to SparkPlan

I'm trying to execute the test query like this:
SELECT COUNT(CASE WHEN name IN (SELECT name FROM requiredProducts) THEN name END)
FROM myProducts
which throws the following exception:
java.lang.ClassCastException:
org.apache.spark.sql.execution.datasources.LogicalRelation cannot be cast to
org.apache.spark.sql.execution.SparkPlan
I have a suggestion that IN operator can not be used in CASE WHEN. Is it really so? Spark documentation is silent about this.
The IN operator using a subquery does not work in a projection regardless of whether it is contained in a CASE WHEN, it will only work in filters. It works fine if you specify values in the IN clause directly rather than using a subquery.
I am not sure how to generate the exact exception you got above, but when I attempt to run a similar query in Spark Scala, it returns a more descriptive error:
org.apache.spark.sql.AnalysisException: IN/EXISTS predicate sub-queries can only be used in a Filter: Project [CASE WHEN agi_label#5 IN (list#96 []) THEN 1 ELSE 0 END AS CASE WHEN (agi_label IN (listquery())) THEN 1 ELSE 0 END#97]
I have run into this issue in the past. Your best bet is probably to restructure it to use a left join to requiredProducts and then check for a null in the case statement. For example, something like this might work:
SELECT COUNT(CASE WHEN rp.name is not null THEN mp.name END)
FROM myProducts mp
LEFT JOIN requiredProducts rp ON mp.name = rp.name

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

Advanced query with kohana ORM

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');

SubSonic.SqlQuery incorrectly generated when using Where()

I am using version 2.1 of SubSonic. I am trying to build to build a relatively simple query where I get a list of Roles for a User using UserId as a parameter. (UserId is a string...)
SubSonic.SqlQuery sel = new SubSonic.Select().From(Data.Tables.Role).InnerJoin(Data.Tables.UserRole, Data.UserRole.Columns.RoleId, Data.Tables.Role, Data.Role.Columns.Id).InnerJoin(Data.Tables.User, Data.User.Columns.Id, Data.Tables.UserRole, Data.UserRole.Columns.UserId).Where("[dbo].[User].[Id]").IsEqualTo(userId);
this generates the query
SELECT [dbo].[Role].[Id], [dbo].[Role].[PID], [dbo].[Role].[Name]
FROM [dbo].[Role]
INNER JOIN [dbo].[UserRole] ON [dbo].[Role].[Id] = [dbo].[UserRole].[RoleId]
INNER JOIN [dbo].[User] ON [dbo].[UserRole].[UserId] = [dbo].[User].[Id]
WHERE [dbo].[User].[Id] = #[dbo].[User].[Id]0
which fails. If I replace the Where with .Where(Data.User.Columns.Id) this generates the query
SELECT [dbo].[Role].[Id], [dbo].[Role].[PID], [dbo].[Role].[Name]
FROM [dbo].[Role]
INNER JOIN [dbo].[UserRole] ON [dbo].[Role].[Id] = [dbo].[UserRole].[RoleId]
INNER JOIN [dbo].[User] ON [dbo].[UserRole].[UserId] = [dbo].[User].[Id]
WHERE [dbo].[Role].[Id] = #Id0
which uses the Role table in the Where clause instead of the User table.
Is this a bug, or am I doing something incorrectly? What would be the correct way to do this? Thanks.
This is fixed in version 2.2 - I would suggest upgrading.

Resources