Laravel and CTE's - laravel

I'm trying to convert the following SQL query into Laravel code using taudenmeirs' laravel-cte package.
WITH `cte` AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY channel_id ORDER BY created_at DESC) AS row_number
FROM `Videos`
)
SELECT `Channels`.*, `cte`.*
FROM `Channels`
LEFT JOIN `cte`
ON `Channels`.`id` = `cte`.`channel_id`
WHERE `cte`.`row_number` = 1;
The problem is I keep getting the following response from the server:
Illuminate\Database\QueryException: SQLSTATE[42000]: Syntax error or
access violation: 1140 Mixing of GROUP columns
(MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there
is no GROUP BY clause (SQL: with cte as (select , ROW_NUMBER() OVER
(PARTITION BY channel_id ORDER BY created_at DESC) AS row_number from
Videos) select Channels. from Channels left join cte on
Channels.id = cte.channel_id where cte.rn = 1) in file
/Users/mark/Workspace/api.site/vendor/laravel/framework/src/Illuminate/Database/Connection.php
on line 665

I actually got this answer from taudenmeirs over on github where I submitted this issue as a bug. It turns out that the error is caused by a bug in MariaDB: https://jira.mariadb.org/browse/MDEV-17785
The ONLY_FULL_GROUP_BY mode is enabled in Laravel by default. You can disable it by setting 'strict' => false in your config/database.php file.
This actually does solve the issue. However it would be better if the fine folks over at Maria could solve the underlying bug.

Related

Implementing the GROUP BY oracle query causing: not a GROUP BY expression in Ruby

My RUBY code executes a oracle query in the following way, but I seem to be getting the error:
Java::JavaSql::SQLSyntaxErrorException: ORA-00979: not a GROUP BY expression
SELECT
"REQUESTS".*
FROM
"REQUESTS"
WHERE
(
customer_id = 1
AND request_method != 'OPTIONS'
AND request_time BETWEEN TO_TIMESTAMP('2021-10-29 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
AND TO_TIMESTAMP(
'2021-11-05 23:59:59.000999',
'YYYY-MM-DD HH24:MI:SS.FF'
)
)
GROUP BY
"REQUESTS"."REQUEST_TIME"
Initially the code which is translated into the above mentioned select query is:
requests = Request.where("customer_id = ? AND request_method != ? AND request_time BETWEEN TO_TIMESTAMP(?,'YYYY-MM-DD HH24:MI:SS') AND TO_TIMESTAMP(?,'YYYY-MM-DD HH24:MI:SS.FF')", customer.id, 'OPTIONS', start_time, end_time).group('date(request_time'))
The
.group('date(request_time') is translated in oracle to: GROUP BY date(request_time)
but it didn't seem to work either which was the original query, and the reason is because Oracle doesn't have this functionality , so I changed it and have been trying in differnt ways but can't seem to figure out why the group by expression wont work.
select * means "select all columns".
Group by clause says group by request_time, which is only one column, and that just won't work.
You'll have to apply group by to ALL columns (specified one-by-one), or - simpler - use select distinct.
Basically, we use group by when there's an aggregation in select column list. If there's none, you don't group by.
What you'll really do depends on what you want to do, i.e. which result you expect.

Column name is not passed to PostgreSQL on JDBC Scan in Apache Drill

While trying to run SQL query for PostgreSQL, instead of the column names from the table referred it it pushing down * to the database.
select
m.m_id,
cnt_c_no
from (
select
m_id
from pg_test_main.test1.table1
where
last_date >= '2019-01-01 00:00:00'
) as m
left join (
select
ci.m_id,
count(ci.c_no) as cnt_c_no
from (
select
m_id,
c_no
from pg_test.public.table2
) as ci
inner join (
select
c_no
from pg_test.public.table3
where
is_del = 'F'
) as c on ci.c_no = c.c_no
group by
ci.m_id
) as join1 on m.m_id = join1.m_id;
00-00 Screen
00-01 Project(m_id=[$0], cnt_c_no=[$1])
00-02 Project(m_id=[$0], cnt_c_no=[$2])
00-03 HashJoin(condition=[=($0, $1)], joinType=[left], semi-join: =[false])
00-05 Jdbc(sql=[SELECT "m_id" FROM "test1"."table1" WHERE "last_date" >= '2019-01-01 00:00:00' ])
00-04 Project(m_id0=[$0], cnt_c_no=[$1])
00-06 HashAgg(group=[{0}], cnt_c_no=[COUNT($1)])
00-07 Project(m_id=[$0], c_no=[$1])
00-08 HashJoin(condition=[=($1, $2)], joinType=[inner], semi-join: =[false])
00-10 Project(m_id=[$3], c_no=[$1])
00-12 Jdbc(sql=[SELECT * FROM "public"."table2" ])
00-09 Project(c_no0=[$0])
00-11 Project(c_no=[$0])
00-13 SelectionVectorRemover
00-14 Filter(condition=[=($60, 'F')])
00-15 Jdbc(sql=[SELECT * FROM "public"."table3" ])
As you can see, Jdbc Scan for table1 was using column names.
but, Jdbc Scan for table2 and table3 was not using column names. It pushed down * to the database.
How can I control jdbc scan so that it can push down colume names?
Apache Drill version is 1.16.0 (embedded-mode)
I tried to reproduce it with MySQL on both Drill 1.17 and Drill 1.15, but for the query, similar to the query you have specified, all the query is pushed into the JDBC storage:
SELECT m.person_id,
cnt_c_no
FROM
(SELECT person_id
FROM mysql.`drill_mysql_test1`.person1
WHERE date_field >= '2019-01-01 00:00:00') AS m
LEFT JOIN
(SELECT ci.person_id,
count(ci.last_name) AS cnt_c_no
FROM
(SELECT person_id,
last_name
FROM mysql.`drill_mysql_test`.person) AS ci
INNER JOIN
(SELECT last_name
FROM mysql.`drill_mysql_test`.person2
WHERE boolean_field = 'F' ) AS c ON ci.last_name = c.last_name
GROUP BY ci.person_id) AS join1 ON m.person_id = join1.person_id
The plan for this query:
00-00 Screen
00-01 Project(person_id=[$0], cnt_c_no=[$1])
00-02 Jdbc(sql=[SELECT `t0`.`person_id`, `t5`.`cnt_c_no` FROM (SELECT `person_id` FROM `drill_mysql_test1`.`person1` WHERE `date_field` >= '2019-01-01 00:00:00') AS `t0` LEFT JOIN (SELECT `t1`.`person_id`, COUNT(`t1`.`last_name`) AS `cnt_c_no` FROM (SELECT `person_id`, `last_name` FROM `drill_mysql_test`.`person`) AS `t1` INNER JOIN (SELECT `last_name` FROM `drill_mysql_test`.`person2` WHERE `boolean_field` = 'F') AS `t3` ON `t1`.`last_name` = `t3`.`last_name` GROUP BY `t1`.`person_id`) AS `t5` ON `t0`.`person_id` = `t5`.`person_id` ])
Could you please provide CTAS for Postgres tables, so I will try to reproduce it again with specific data types. Also, if possible, please check whether this issue is still reproduced on Drill 1.17.
UPD:
Comment under this answer helped to discover that this problem was caused by the following issue: https://issues.apache.org/jira/browse/DRILL-7340 and it will be resolved in Drill 1.18.0.

Laravel 5.3 Complex DB Update Query with Select, Joins and CONCAT notworking

I wrote an sql update query. It is working on Mysql Workbench. I put the sql update query in laravels db update. When I am testing it with phpunit I am getting an error. The phpunit uses sqlite.
The following error appears when I run the unit test:
Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 near "as": syntax error (SQL: UPDATE table1 as mainp LEFT JOIN ....)
When I am removing "as mainp" the following error appears:
Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 near "LEFT": syntax error (SQL: UPDATE table1 as mainp LEFT JOIN ....)
Here is the whole update query
\DB::connection($this->dbConnection)->update(\DB::raw("
UPDATE table1 as mainp left join
(
SELECT *
FROM
(
select p.fullname, cc.surname as name_one, cc.forename as name_two
from table1 as p
LEFT JOIN table2 as cc
on p.fullname LIKE CONCAT(cc.surname,'%')
LEFT JOIN table2 as cc2
on p.fullname LIKE CONCAT('%',cc.forename)
) AS pcccc
WHERE fullname = CONCAT(name_one, name_two)
) AS main
ON mainp.fullname = main.fullname
SET mainp.name_one = main.name_one,
mainp.name_two = main.name_two")
);
All the tables are created. When I am using db::select I am getting some result.
return \DB::connection($this->dbConnection)->select(\DB::raw("select p.fullname, cc.surname as name_one, cc.forename as name_two
from table1 as p
LEFT JOIN table2 as cc
on p.fullname LIKE CONCAT(cc.surname,'%')
LEFT JOIN table2 as cc2
on p.fullname LIKE CONCAT('%',cc.forename)"));
What I am doing wrong?

Issue with Spring data jpa Db2 pagination

I am using Spring JPA with DB2, when i use paging repository and queries for second page it throws error.
This is the generated query
SELECT *
FROM (SELECT inner2_.*,
ROWNUMBER()
OVER(
ORDER BY ORDER OF inner2_) AS rownumber_
FROM (SELECT db2DATAa0_.c_type AS col_0_0_,
db2DATAa0_.h_proc AS col_1_0_,
db2DATAa0_.n_vin AS col_2_0_,
db2DATAa0_.i_cust AS col_3_0_
FROM dcu.v_rpt_data_hist db2DATAa0_
WHERE db2DATAa0_.reportid = '0H000488089'
AND ( db2DATAa0_.c_type = 'S'
OR db2DATAa0_.c_type = 'N'
OR db2DATAa0_.c_type = 'A'
OR db2DATAa0_.c_type = 'T' )
ORDER BY db2DATAa0_.h_proc desc
FETCH first 30 ROWS only) AS inner2_) AS inner1_
WHERE rownumber_ > 15
ORDER BY rownumber_
Error:
2719372 [2016-10-21 16:29:02,040] [RxCachedThreadScheduler-13] WARN org.hibern
ate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: -199, SQLState: 42601
2719379 [2016-10-21 16:29:02,047] [RxCachedThreadScheduler-13] ERROR org.hibern
ate.engine.jdbc.spi.SqlExceptionHelper - DB2 SQL Error: SQLCODE=-199, SQLSTATE=
42601, SQLERRMC=OF;??( [ DESC ASC NULLS RANGE CONCAT || / MICROSECONDS MICROSECO
ND, DRIVER=3.57.82
Any idea?
Your error states the ILLEGAL USE OF KEYWORD OF. TOKEN [DESC ASC NULLS RANGE CONCAT] WAS EXPECTED.
I identified this as the critical part of the query:
ORDER BY ORDER OF inner2_
DB2 expects one of DESC, ASC, NULLS, RANGE, CONCAT after the second ORDER keyword.
This issue can be resolve by change dialect.
Change dialect in configuration or property file to DB2ZOSDialect

ORA-00904: invalid column name but I am using the correct column name

Can someone see where I am going wrong in the below query? I am getting the error message that the GROUP BY column doesn't exist, but it clearly does as I see that column name in the output when I don't use the GROUP BY.
SELECT
(SELECT customer_address.post_code FROM customer_address WHERE customer_address.address_type = 0 AND customer_address.customer_no = orders.customer_no) postcode, SUM(orders.order_no) orders
FROM
orders, customer_address
WHERE
orders.delivery_date = '27-MAY-15'
GROUP BY
postcode;
The answer is: You cannot use an alias name in GROUP BY.
So:
GROUP BY (SELECT customer_address.post_code ...);
Or:
select postcode, sum(order_no)
from
(
SELECT
(SELECT customer_address.post_code FROM customer_address WHERE customer_address.address_type = 0 AND customer_address.customer_no = orders.customer_no) postcode,
orders.order_no
FROM orders, customer_address
WHERE orders.delivery_date = '27-MAY-15'
)
GROUP BY postcode;
EDIT:
However, your query seems wrong. Why do you cross-join orders and customer_address? By mistake I guess. Use explicit joins (INNER JOIN customer_address ON ...), when using joins to avoid such errors. But here I guess you'd just have to remove , customer_address.
Then why do you add order numbers? That doesn't seem to make sense.

Resources