I have following DQL query
SELECT
ps.id,
MAX(ps.dueDate) as due_date,
u.firstName as first_name,
u.lastName as last_name,
u.email,
IDENTITY(ps.loanApplication) as loan_application_id,
DATE_DIFF(MAX(ps.dueDate), CURRENT_DATE()) as diff
FROM
Loan\Entity\PaymentSchedule ps
LEFT JOIN
ps.paymentType pt
LEFT JOIN
ps.loanApplication la
LEFT JOIN
la.status s
LEFT JOIN
la.user u
WHERE
pt.slug != :paymentSlug AND s.keyIdentifier = :status AND diff = 14
GROUP BY
ps.loanApplication
Which translates to following SQL query
SELECT
p0_.id AS id_0,
MAX(p0_.due_date) AS sclr_1,
u1_.first_name AS first_name_2,
u1_.last_name AS last_name_3,
u1_.email AS email_4,
p0_.loan_application_id AS sclr_5,
DATEDIFF(MAX(p0_.due_date), CURRENT_DATE) AS sclr_6
FROM
payment_schedule p0_
LEFT JOIN
payment_type p2_ ON p0_.payment_type_id = p2_.id
LEFT JOIN
loan_application l3_ ON p0_.loan_application_id = l3_.id
LEFT JOIN
loan_application_status l4_ ON l3_.loan_application_status_id = l4_.id
LEFT JOIN
user u1_ ON l3_.user_id = u1_.id
WHERE
p2_.slug <> ? AND l4_.key_identifier = ? AND sclr_6 = 14
GROUP BY
p0_.loan_application_id
This gives me following error
======================================================================
PDOException
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'sclr_6' in 'where clause'
----------------------------------------------------------------------
When i replace WHERE condition
WHERE pt.slug != :paymentSlug AND s.keyIdentifier = :status AND diff = 14
With
WHERE pt.slug != :paymentSlug AND s.keyIdentifier = :status
It works perfectly and displays me correct record, i also tried following WHERE condition
WHERE pt.slug != :paymentSlug AND s.keyIdentifier = :status AND DATE_DIFF(MAX(ps.dueDate), CURRENT_DATE()) = :days_diff
WHERE pt.slug != :paymentSlug AND s.keyIdentifier = :status HAVING (DATE_DIFF(MAX(ps.dueDate), CURRENT_DATE())) = :days_diff
Above WHERE does not work as well, what am i missing here ?
Thanks.
If you want to use the alias in your WHERE clause you need a sub-select.
select *
from
(SELECT
p0_.id AS id_0,
MAX(p0_.due_date) AS sclr_1,
u1_.first_name AS first_name_2,
u1_.last_name AS last_name_3,
u1_.email AS email_4,
p0_.loan_application_id AS sclr_5,
DATEDIFF(MAX(p0_.due_date), CURRENT_DATE) AS sclr_6
FROM
payment_schedule p0_
LEFT JOIN
payment_type p2_ ON p0_.payment_type_id = p2_.id
LEFT JOIN
loan_application l3_ ON p0_.loan_application_id = l3_.id
LEFT JOIN
loan_application_status l4_ ON l3_.loan_application_status_id = l4_.id
LEFT JOIN
user u1_ ON l3_.user_id = u1_.id
) A
WHERE
slug <> ? AND key_identifier = ? AND sclr_6 = 14
This is how query is logically processed
FROM clause
WHERE clause
SELECT clause
GROUP BY clause
HAVING clause
ORDER BY clause
Since Where comes before Select you cannot use alias name in Where clause
You cannot use an alias (on the final result fields) in the WHERE clause; however, at least with MySQL, you may use a HAVING clause without needing a GROUP BY.
The expression you are using is the result of an aggregation. Replace add a having clause so the query looks like;
SELECT . . .
WHERE p2_.slug <> ? AND l4_.key_identifier = ?
GROUP BY p0_.loan_application_id
HAVING sclr_6 = 14
Note that date_diff() is not a function in MySQL. You intend datediff().
Related
I have created Query Which Gives error of only_full_group_by. I Want To change Query Not SET sql_mode=only_full_group_by
#1055 - Expression #4 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'hrdk.s.item_stock_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by#
This is the query that is giving me trouble:
SELECT `s`.`department_id`, `s`.`category_id`, `s`.`item_id`, `s`.`item_stock_id`, `s`.`tunch`, `cat`.`category_name`, `im`.`item_name`, `im`.`stock_method`, `cat`.`category_group_id`, SUM(s.grwt) AS grwt, SUM(s.ntwt) AS ntwt, sum(s.less) AS less, SUM(s.fine) AS fine
FROM `item_stock` `s`
LEFT JOIN `item_master` `im` ON `im`.`item_id` = `s`.`item_id`
LEFT JOIN `account` `pm` ON `pm`.`account_id` = `s`.`department_id`
LEFT JOIN `category` `cat` ON `cat`.`category_id` = `s`.`category_id`
WHERE (im.stock_method = 1 AND (`s`.`grwt` =0 OR `s`.`grwt` !=0)
OR (`im`.`stock_method` = 2 AND `s`.`grwt` != 0))
AND s.department_id IN(26,27,28,29,30,31,32,59)
AND `s`.`grwt` !=0
AND `s`.`department_id` = '26'
GROUP BY `s`.`category_id`, `s`.`item_id`, if(`im`.`stock_method` = 1, `s`.`tunch`, "")
ORDER BY `s`.`item_stock_id` DESC
Let me know if you need more information.
You've to add all non aggregated columns in group by
SELECT s.department_id, s.category_id, s.item_id, s.item_stock_id, s.tunch, cat.category_name, im.item_name, im.stock_method, cat.category_group_id, SUM(s.grwt) AS grwt, SUM(s.ntwt) AS ntwt, sum(s.less) AS less, SUM(s.fine) AS fine
FROM item_stock s LEFT JOIN item_master im ON im.item_id = s.item_id
LEFT JOIN account pm ON pm.account_id = s.department_id
LEFT JOIN category cat ON cat.category_id = s.category_id
WHERE (im.stock_method = 1 AND (s.grwt =0 OR s.grwt !=0) OR (im.stock_method = 2 AND s.grwt != 0))AND s.department_id IN(26,27,28,29,30,31,32,59) AND s.grwt !=0 AND s.department_id = '26'
GROUP BY s.department_id, s.category_id, s.item_id, s.item_stock_id, s.tunch, cat.category_name, im.item_name, im.stock_method, cat.category_group_id
ORDER BY s.item_stock_id DESC
I'm using Hibernate 4.3.11 and MySQL 5.7.11.
I wanted to rewrite this MySQL query to HQL:
SELECT COALESCE(g1.id, g2.id) as id, COALESCE(g1.type, g2.type) as type, COALESCE(g1.email_id, g2.email_id) as email_id, COALESCE(g1.url_id, g2.url_id) as url_id FROM notifications n
LEFT JOIN emails ON emails.id = n.email_id
LEFT JOIN urls ON urls.id = n.url_id
LEFT JOIN notifications_group g1 ON g1.email_id = n.email_id
LEFT JOIN notifications_group g2 ON g2.url_id = n.url_id
WHERE (((n.type = 'EMAIL' OR n.type = 'REMINDER') AND n.email_id is not null AND emails.user_id = :userId)
OR (n.type = 'URL' AND n.url_id is not null AND urls.user_id = :userId))
AND (g1.id is not null OR g2.id is not null)
AND ((g1.id is not null AND g1.id < :beforeId) OR (g2.id is not null AND g2.id < :beforeId))
GROUP BY COALESCE(g1.id, g2.id)
ORDER BY MAX(n.id) DESC
I have rewritten this native query to HQL:
SELECT COALESCE(g1.id, g2.id), COALESCE(g1.type, g2.type), COALESCE(g1.email, g2.email), COALESCE(g1.url, g2.url) FROM Notification n
LEFT JOIN n.email e
LEFT JOIN n.url u
LEFT JOIN e.notificationGroup g1
LEFT JOIN u.notificationGroup g2
WHERE (((n.type = delimail.enums.NotificationType.EMAIL OR n.type = delimail.enums.NotificationType.REMINDER) AND e IS NOT NULL AND e.user = :user)
OR (n.type = delimail.enums.NotificationType.URL AND u IS NOT NULL AND u.user = :user))
AND (g1 IS NOT NULL OR g2 IS NOT NULL)
AND ((g1.id IS NOT NULL AND g1.id < :beforeId) OR (g2 IS NOT NULL AND g2.id < :beforeId))
GROUP BY COALESCE(g1.id, g2.id), COALESCE(g1.type, g2.type), COALESCE(g1.email, g2.email), COALESCE(g1.url, g2.url)
ORDER BY MAX(n.id)
But it don't work. Hibernate generates this query:
SELECT coalesce(notificati3_.id, notificati4_.id) AS col_0_0_,
coalesce(notificati3_.type, notificati4_.type) AS col_1_0_,
coalesce(notificati3_.email_id, notificati4_.email_id) AS col_2_0_,
coalesce(notificati3_.url_id, notificati4_.url_id) AS col_3_0_
FROM delimail.notifications notificati0_
LEFT OUTER JOIN delimail.emails email1_ ON notificati0_.email_id=email1_.id
LEFT OUTER JOIN delimail.notifications_group notificati3_ ON email1_.id=notificati3_.email_id,
delimail.emails email5_, --l 8
delimail.urls url7_ --l 9
LEFT OUTER JOIN delimail.urls url2_ ON notificati0_.url_id=url2_.id --error: Unknown column 'notificati0_.url_id' in 'on clause'
LEFT OUTER JOIN delimail.notifications_group notificati4_ ON url2_.id=notificati4_.url_id,
delimail.emails email6_, --l 12
delimail.urls url8_ --l 13
WHERE notificati3_.email_id=email5_.id --l 14
AND notificati3_.url_id=url7_.id --l 15
AND notificati4_.email_id=email6_.id --l 16
AND notificati4_.url_id=url8_.id --l 17
AND ((notificati0_.type='EMAIL'
OR notificati0_.type='REMINDER')
AND (email1_.id IS NOT NULL)
AND email1_.user_id=?
OR notificati0_.type='URL'
AND (url2_.id IS NOT NULL)
AND url2_.user_id=?)
AND (notificati3_.id IS NOT NULL
OR notificati4_.id IS NOT NULL)
AND ((notificati3_.id IS NOT NULL)
AND notificati3_.id<?
OR (notificati4_.id IS NOT NULL)
AND notificati4_.id<?)
GROUP BY coalesce(notificati3_.id, notificati4_.id),
coalesce(notificati3_.type, notificati4_.type),
coalesce(notificati3_.email_id, notificati4_.email_id),
coalesce(notificati3_.url_id, notificati4_.url_id)
ORDER BY MAX(notificati0_.id)
And the error is:
Unknown column 'notificati0_.url_id' in 'on clause'
SQL Warning Code: 1054, SQLState: 42S22
But this query works as expected after removing marked lines 8-9, 12-13, and removing conditions in lines 14-17.
How can I convert this query to HQL? If it's possible.
I guess in this case since the query is kind of complex, You can very well go for native Query
Please see sample below:
String q="select employee_name from employee";
Query query= em.createNativeQuery(q,Object[].class);
List<Object[]> students= query.getResultList();
Please refer to the documentation below :
http://docs.oracle.com/javaee/7/api/javax/persistence/EntityManager.html#createNativeQuery-java.lang.String-
I have a query that works well, where i would like an assistance is how to incorporate a condition to determine the value displayed on a given column. That is if a column of a table has a value say "Authorization of COA" then the column date added should show the date else the column should show null
Here is my query so far
SELECT r.request_id, r.product_name, r.created_at, r.can,a_s.stat, r.client_id, CONCAT(u.fname,' ',u.lname) 'analyst' , t.date_added (//should show the value of date_added else NULL based on a condition for this column),
FROM request r
LEFT OUTER JOIN assigned_samples a_s ON r.request_id = a_s.labref
LEFT OUTER JOIN user u ON a_s.analyst_id = u.id
LEFT OUTER JOIN tracking_table t ON r.request_id = t.labref
WHERE r.client_id='$cid'
AND r.created_at BETWEEN '$start' AND '$end'
AND a_s.department_id = '$dept'
GROUP BY r.request_id
ORDER BY `r`.`created_at` DESC "
A simple CASE statement should be sufficient in this case, I believe.
SELECT r.request_id, r.product_name, r.created_at, r.can,a_s.stat, r.client_id,
CONCAT(u.fname,' ',u.lname) 'analyst',
CASE WHEN ConditionColumn = 'Authorization of COA' THEN t.date_added
ELSE NULL END AS 'date_added'
FROM request r
LEFT OUTER JOIN assigned_samples a_s ON r.request_id = a_s.labref
LEFT OUTER JOIN user u ON a_s.analyst_id = u.id
LEFT OUTER JOIN tracking_table t ON r.request_id = t.labref
WHERE r.client_id='$cid'
In both mysql and ms sql you can use case expression (mysql case; ms sql case) to assign value to a field conditionally:
SELECT r.request_id, r.product_name, r.created_at, r.can,a_s.stat, r.client_id, CONCAT(u.fname,' ',u.lname) 'analyst' ,
CASE WHEN Column_To_Test = 'Authorization of COA' THEN t.date_added
ELSE null
END AS date_added
FROM request r
LEFT OUTER JOIN assigned_samples a_s ON r.request_id = a_s.labref
LEFT OUTER JOIN user u ON a_s.analyst_id = u.id
LEFT OUTER JOIN tracking_table t ON r.request_id = t.labref
WHERE r.client_id='$cid'
AND r.created_at BETWEEN '$start' AND '$end'
AND a_s.department_id = '$dept'
GROUP BY r.request_id
ORDER BY `r`.`created_at` DESC "
This way the solution is more portable between the databases. Mysql offers if() function, ms sql iif() to achieve the above, but those are product specific solutions.
Try to use the Case statements like.
CASE WHEN ( Condition_1 AND Condition_2 OR ... Condition_N) THEN (Value_1) ELSE (Value_1) END
Here Condition_1 can be column record value and its combination of Column record values
and Value_1 can be single value [Ex: Null or "some string"] or Returned value from nested sql statement like [Ex: (select count(*) from ...)]
Give this a try:
SELECT r.request_id, r.product_name, r.created_at, r.can,a_s.stat, r.client_id, CONCAT(u.fname,' ',u.lname) 'analyst' ,
IFF(nameOfColumnToTest = 'Authorization of COA', t.date_added, null) AS DateAdded
FROM request r
LEFT OUTER JOIN assigned_samples a_s ON r.request_id = a_s.labref
LEFT OUTER JOIN user u ON a_s.analyst_id = u.id
LEFT OUTER JOIN tracking_table t ON r.request_id = t.labref
WHERE r.client_id='$cid'
AND r.created_at BETWEEN '$start' AND '$end'
AND a_s.department_id = '$dept'
GROUP BY r.request_id
ORDER BY `r`.`created_at` DESC "
SELECT
E.`employee_id`,
E.`full_name`,
LE.`no_of_leaves` AS AllocatedLeaves,
MLLT.`leave_type` AS LeaveTypeName,
COUNT(SELECT * FROM leave_approval WHERE employee_id = 1) AS TotalLeavesTaken
FROM employee E
INNER JOIN leave_entitlement LE
ON E.`employee_id` = LE.`employee_id`
INNER JOIN `ml_leave_type` MLLT
ON MLLT.`ml_leave_type_id` = LE.`ml_leave_type_id`
LEFT JOIN leave_approval LA
ON E.`employee_id` = LA.`employee_id`
LEFT JOIN leave_application LAPP
ON LAPP.`application_id` = LA.`leave_application_id`
LEFT JOIN ml_leave_type MLLTLA
ON MLLTLA.`ml_leave_type_id` = LAPP.`ml_leave_type_id`
i am getting syntax error near count, but i tried to find out the syntax error and i could not find any?
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from leave_approval where employee_id = 1) AS TotalLeavesTaken
from emp' at line 6
Is it really a syntax error. or is there something i am missing here??
This line:
COUNT(SELECT * FROM leave_approval WHERE employee_id = 1) AS TotalLeavesTaken
is incorrect. You can not do a count on select * subquery without placing it in parentheses, but even then you'd need a group by and additional logic. The better approach would be:
(Select count(*) from leave_approval where employee_id = 1) AS TotalLeavesTaken
change
COUNT(SELECT * FROM leave_approval WHERE employee_id = 1) AS TotalLeavesTaken
to
(SELECT count(*) FROM leave_approval WHERE employee_id = 1) AS TotalLeavesTaken
No need to use subquery for count in your case check below query
Try this:
SELECT E.employee_id, E.full_name, LE.no_of_leaves AS AllocatedLeaves,
MLLT.leave_type AS LeaveTypeName,
SUM(CASE WHEN LA.employee_id = 1 THEN 1 ELSE 0 END) AS TotalLeavesTakenByEmplyeeNo1
FROM employee E
INNER JOIN leave_entitlement LE ON E.employee_id = LE.employee_id
INNER JOIN `ml_leave_type` MLLT ON MLLT.ml_leave_type_id = LE.ml_leave_type_id
LEFT JOIN leave_approval LA ON E.employee_id = LA.employee_id
LEFT JOIN leave_application LAPP ON LAPP.application_id = LA.leave_application_id
LEFT JOIN ml_leave_type MLLTLA ON MLLTLA.ml_leave_type_id = LAPP.ml_leave_type_id
GROUP BY E.employee_id;
Try This Query
SELECT E.`employee_id`,E.`full_name`,LE.`no_of_leaves` AS AllocatedLeaves,MLLT.`leave_type` AS LeaveTypeName,
SUM( CASE WHEN LA.employee_id = '1' THEN 1 ELSE 0 END ) as TotalLeavesTaken
FROM employee E
INNER JOIN leave_entitlement LE
ON E.`employee_id` = LE.`employee_id`
INNER JOIN `ml_leave_type` MLLT
ON MLLT.`ml_leave_type_id` = LE.`ml_leave_type_id`
LEFT JOIN leave_approval LA
ON E.`employee_id` = LA.`employee_id`
LEFT JOIN leave_application LAPP
ON LAPP.`application_id` = LA.`leave_application_id`
LEFT JOIN ml_leave_type MLLTLA
ON MLLTLA.`ml_leave_type_id` = LAPP.`ml_leave_type_id`
Only you have to replace COUNT(SELECT * FROM leave_approval WHERE employee_id = 1) to SUM( CASE WHEN LA.employee_id = '1' THEN 1 ELSE 0 END )
Thanks it, Try this because i have tried this query and it will give you perfect result
I have some trouble to count more than 2 counts in mysql statement.
My count(b.entry_id) as totalbooking wont work. What have i done wrong? Is the statement setup also correctly made?
This is how i tried:
"SELECT
t.restaurant_id as restaurant_id, ct.title as title,
count(DISTINCT t.cardid) as totalmembers,
count(t.restaurant_id) as totaltransactions,
count(b.entry_id) as totalbooking
from transactions as t
inner join exp_menucard_booking as b on (t.restaurant_id = b.entry_id)
inner join exp_channel_titles as ct on (t.restaurant_id = ct.entry_id)
inner JOIN exp_channel_data as cd on (ct.entry_id = cd.entry_id)
where t.cardid != 88888888 and ct.status = 'open'
group by t.restaurant_id
order by ct.title asc";
Use this pattern to count subsets of the total rowset:
sum( case when ColumnToBeTested = trueCondition then 1 else 0 end) as SubCount