how do I get the max date value of a union tables? Whenever I use GROUP BY, I only get the max date value of the first table. So far, here's my code:
SELECT * FROM ((SELECT tc.id, tc.personnel_id, tpi.emp_status, tpi.firstname, tpi.lastname, tc.date_from, tc.date_to FROM tbl_contracts AS tc
JOIN (SELECT personnel_id, MAX(date_to) AS Maxdatetime
FROM tbl_contracts
GROUP BY personnel_id) AS r
ON tc.personnel_id = r.personnel_id AND tc.date_to = r.Maxdatetime
LEFT JOIN tbl_personnel_info AS tpi
ON tpi.id = tc.personnel_id
WHERE tpi.firstname LIKE CONCAT('%', '', '%')
AND tpi.lastname LIKE CONCAT('%', '', '%')
ORDER BY tc.date_to DESC)
UNION ALL
(SELECT tpss.id, tpss.personnel_id, tpi.emp_status, tpi.firstname, tpi.lastname, tpss.date_from, tpss.date_to
FROM tbl_personnel_sea_service AS tpss
JOIN (
SELECT personnel_id, MAX(date_to) AS Maxdatetime
FROM tbl_personnel_sea_service
GROUP BY personnel_id
) AS r
ON tpss.personnel_id = r.personnel_id AND tpss.date_to = r.Maxdatetime
LEFT JOIN tbl_personnel_info AS tpi
ON tpi.id = tpss.personnel_id
WHERE tpi.firstname LIKE CONCAT('%', '', '%')
AND tpi.lastname LIKE CONCAT('%', '', '%')
AND agency_name = 'UMMI'
ORDER BY tpss.date_to DESC)) AS tmain
GROUP BY tmain.personnel_id
The result is correct. However if I use GROUP BY tmain.personnel_id, sorting result is wrong. It's not getting the max date value of the second table
I'd suggest you take the group by over all the column and aggregate the date and finally order by date_to (or whichever column/s you need)-
SELECT personnel_id,
emp_status,
first_name,
lastname,
MIN(date_from) date_from,
MAX(date_to) date_to
FROM (
(SELECT tc.id,
tc.personnel_id,
tpi.emp_status,
tpi.firstname,
tpi.lastname,
tc.date_from,
tc.date_to
FROM tbl_contracts AS tc
JOIN
(SELECT personnel_id,
MAX(date_to) AS Maxdatetime
FROM tbl_contracts
GROUP BY personnel_id
) AS r
ON tc.personnel_id = r.personnel_id
AND tc.date_to = r.Maxdatetime
LEFT JOIN tbl_personnel_info AS tpi
ON tpi.id = tc.personnel_id
WHERE tpi.firstname LIKE CONCAT('%', '', '%')
AND tpi.lastname LIKE CONCAT('%', '', '%')
ORDER BY tc.date_to DESC
)
UNION ALL
(SELECT tpss.id,
tpss.personnel_id,
tpi.emp_status,
tpi.firstname,
tpi.lastname,
tpss.date_from,
tpss.date_to
FROM tbl_personnel_sea_service AS tpss
JOIN
(SELECT personnel_id,
MAX(date_to) AS Maxdatetime
FROM tbl_personnel_sea_service
GROUP BY personnel_id
) AS r
ON tpss.personnel_id = r.personnel_id
AND tpss.date_to = r.Maxdatetime
LEFT JOIN tbl_personnel_info AS tpi
ON tpi.id = tpss.personnel_id
WHERE tpi.firstname LIKE CONCAT('%', '', '%')
AND tpi.lastname LIKE CONCAT('%', '', '%')
AND agency_name = 'UMMI'
ORDER BY tpss.date_to DESC
)) AS tmain
GROUP BY personnel_id,
emp_status,
first_name,
lastname
ORDER BY date_to
Related
hi i need help combining 2 cte to get who get 100 attendance percentage but failed at exam
here my first cte
with main as(
select ca.STUDENT_ID,
ca.SCHEDULE_ID,
s.COURSE_ID,
co.NAME as course_name,
st.NAME,
count(ca.ID) as total_attendance,
((CHAR_LENGTH(s.COURSE_DAYS) - CHAR_LENGTH(REPLACE(s.COURSE_DAYS , ',', '')) + 1) * 13) as attendance_needed
from univ.course_attendance ca
left join univ.schedule s on ca.SCHEDULE_ID = s.ID
left join univ.student st on ca.SCHEDULE_ID = st.ID
left join univ.course co on ca.SCHEDULE_ID = co.ID
group by ca.STUDENT_ID, ca.SCHEDULE_ID
)
select *,total_attendance/attendance_needed as attendance_percentage
from main
order by 1,2;
second cte
;with inputdata as
(
select es.STUDENT_ID,es.EXAM_ID,es.SCORE,e.PASS_THRESHOLD, s.NAME , c.NAME as Course_name, es.EXAM_DT,
case
when SCORE>=PASS_THRESHOLD then 'PASS'
else 'Fail'
end as Flag
from exam_submission es
left join student s on es.STUDENT_ID = s.ID
left join exam e on es.EXAM_ID = e.ID
left join course c on e.COURSE_ID = c.ID
)
select * from inputdata I
join
( select student_id,exam_id from
inputdata
group by student_id, exam_id
)T on I.student_id=T.student_id and I.exam_id=T.exam_id
order by exam_dt asc
result:
what i need student name, course name, attendace percentage & flag "failed/pass"
Just chain multiple table expressions in a single CTE by introducing "aliases" like main_ordered for the first CTE and inputdata_grouped for the second one. I'm sticking with the original naming, but it could be improved.
with
main as (
select ca.STUDENT_ID,
...
group by ca.STUDENT_ID, ca.SCHEDULE_ID),
main_ordered as (
select *,total_attendance/attendance_needed as attendance_percentage
...
order by 1,2),
inputdata as (
select es.STUDENT_ID,es.EXAM_ID,es.S...
...),
inputdata_grouped as (
select * from inputdata I
...
group by student_id, exam_id...
...
order by exam_dt asc)
select *
from main_ordered join inputdata_grouped on ...
SELECT X.workorder_id,X.order_id FROM mr_workorder_data AS X
LEFT JOIN
(SELECT order_id, workorder_id, GROUP_CONCAT(trim_id SEPARATOR '|') AS trim_id_arr
FROM mr_workorder_data
WHERE order_id = X.order_id AND workorder_id =
X.workorder_id GROUP BY order_id)
WHERE X.data_type = 'Accessories' GROUP BY X.workorder_id
You have a left join ( subselect ) without an alias add (eg:) T at the end of the subquery ()
SELECT X.workorder_id,X.order_id
FROM mr_workorder_data AS X
LEFT JOIN ( SELECT order_id,workorder_id,
GROUP_CONCAT(trim_id SEPARATOR '|') AS trim_id_arr
FROM mr_workorder_data
WHERE order_id = X.order_id AND workorder_id = X.workorder_id
GROUP BY order_id ) T
WHERE X.data_type = 'Accessories'
GROUP BY X.workorder_id
so i had to adjust a query i used because the limit at the end of the table would cause the entire first table to be read before limiting. this resulted in a timeout from my mysql server. now i created the query like i read in another post on stack overflow and came up with this:
SELECT a.title
, a.lat
, a.lon
, a.a_content_id
, a.date_added
, r.countRep
, i.countInt
, content.img
, c.marker
, c.subcatvan
FROM
( SELECT title
, lat
, lon
, alert_content_id
, date_added
, cat
FROM alerts
LIMIT 10
) a
LEFT
JOIN
( SELECT COUNT(DISTINCT id) countRep
FROM reply
WHERE alert_id = alerts.alerts
) r
LEFT
JOIN
( SELECT COUNT(DISTINCT id) countInt
FROM interactions
WHERE alert_id = alerts.alerts
) i
LEFT
JOIN
( SELECT img
FROM alerts_content
WHERE alert_id = alerts.alerts
) content
LEFT
JOIN
( SELECT marker
, subcatvan
FROM categories
WHERE a.cat = id
) c;
#1064 - 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 '' at line 45
This was my original query which resulted in a timeout:
SELECT
a.title, a.lat, a.lon, a.alert_content_id, a.date_added, count(DISTINCT r.id) as countRep ,count(DISTINCT i.id) AS countInt,
ac.img, c.marker, c.subcatvan
FROM `alerts` a
LEFT JOIN
`reply` r ON r.alert_id = a.alerts
LEFT JOIN
`interactions` i ON i.alert_id = a.alerts
LEFT JOIN
`alerts_content` ac ON ac.alert_id = a.alerts
LEFT JOIN
`categories` c ON a.cat = c.id
GROUP BY a.title, a.lat, a.lon, a.alert_content_id, a.date_added LIMIT 0,10
Does anyone know what is causing the error?
Or someone that knows how to correct my original query?
You need to fix the subqueries. They need to use group by rather than be correlated:
SELECT a.title, a.lat, a.lon, a.a_content_id, a.date_added, r.countRep,
i.countInt, content.img, c.marker, c.subcatvan
FROM (SELECT title, lat, lon, alert_content_id, date_added, cat
FROM `alerts`
LIMIT 10
) a LEFT JOIN
(SELECT alert_id, count(DISTINCT id) as countRep
FROM `reply`
GROUP BY alert_id
) r
ON r.alert_id = a.alerts r LEFT JOIN
(SELECT alert_id, count(DISTINCT id) AS countInt
FROM `interactions`
GROUP BY alert_id
) i
ON i alert_id = a.alerts LEFT JOIN
(SELECT alert_id, img
FROM `alerts_content`
GROUP BY alert_id
) content
ON alert_id = a.alerts LEFT JOIN
`categories` c
ON a.cat = c.id;
Try adding the table name to the id, in the where.
c.id instead of id
Fixed it thanks to #Ravinder his comment about missing the on clause
updated sql:
SELECT
a.alerts, a.title, a.lat, a.lon, a.alert_content_id, a.date_added, r.countRep, i.countInt,
ac.img, c.marker, c.subcatvan
FROM
(SELECT alerts, title, lat, lon, alert_content_id, date_added, cat
FROM `alerts` LIMIT 10) a
LEFT JOIN
(SELECT alert_id,count(DISTINCT id) as countRep
FROM `reply`) r
ON r.alert_id = a.alerts
LEFT JOIN
(SELECT alert_id,count(DISTINCT id) AS countInt
FROM `interactions`) i
ON i.alert_id = a.alerts
LEFT JOIN
(SELECT alert_id, img
FROM `alerts_content`) ac
ON ac.alert_id = a.alerts
LEFT JOIN
(SELECT id, marker, subcatvan
FROM `categories`) c
ON a.cat = c.id
GROUP BY a.title, a.lat, a.lon, a.alert_content_id, a.date_added
I want to do this query:
SELECT *
FROM user k
INNER JOIN (
SELECT id, tagName, b.guid, name, owner, publicKey
FROM noteTags a
INNER JOIN (
SELECT *
FROM note
ORDER BY guid
LIMIT 0 , 12
)b ON a.guid = b.guid ORDER BY b.id DESC
)l ON k.owner = l.owner
But I want it to return DISTINCT b.guids.
Structure of the tables:
note
|
|=id
|=name
|=guid
|=owner
|=publicKey
noteTags
|
|=guid
|=tagName
user
|
|=owner
|=username
|=auth
Basically I want to select ALL data (with the limit on the deeper inner join) and return DISTINCT guids
Thanks!
Here's my initial answer,
SELECT *
FROM note a
INNER JOIN user b
ON a.owner = b.owner
INNER JOIN notetags c
ON a.guid = b.guid
INNER JOIN
(
SELECT guid, MAX(tagName) maxTag
FROM notetags
GROUP BY guid
) d ON c.guid = d.guid AND
c.tagName = d.maxTag
How about:
SELECT *
FROM user k
INNER JOIN (
SELECT id, tagName, b.guid, name, owner, publicKey
FROM noteTags a
INNER JOIN (
select id, name, MIN(guid) as guid, owner, publicKey
FROM note
GROUP BY guid
LIMIT 0 , 12
)b ON a.guid = b.guid ORDER BY b.id DESC
)l ON k.owner = l.owner
I just added a table which holds a url and description for each item in place. The below query works ok ... but it's only returning the url and I need the desc also. I m not sure how to make this work.
$query_str = "SELECT a.userid, a.cat, a.id, a.name, a.image,
a.desc, a.country, b.user_id, c.username,
c.fbook, d.cat_id,
(
SELECT GROUP_CONCAT(url)
FROM one_add o
WHERE a.id=o.one_id
) AS url,
(
SELECT COUNT(id)
FROM one_msg m
WHERE m.guest_id = ? AND
m.one_id=a.id
) AS count
FROM place a
LEFT OUTER JOIN wait b
ON a.id=b.post_id AND
b.user_id= ?
JOIN users c
ON a.userid=c.id
LEFT JOIN (
SELECT userid, user_id,
GROUP_CONCAT( cat_id ) AS cat_id
FROM user_cat
WHERE userid='$user_id'
GROUP BY user_id
) AS d ON d.userid='$user_id' AND
d.user_id=a.userid
WHERE a.cat != ? ORDER BY a.date desc";
This is what I want to accomplish: desc
You can achibe this by using CONCAT inside GROUP_CONCAT function as:
(SELECT GROUP_CONCAT(CONCAT('',desc,''))
FROM one_add o
WHERE a.id=o.one_id) AS url
full query:
(SELECT COUNT(id) FROM one_msg m WHERE m.guest_id = ? AND m.one_id=a.id ) AS count
FROM place a
LEFT OUTER JOIN wait b ON a.id=b.post_id AND b.user_id= ?
JOIN users c ON a.userid=c.id
LEFT JOIN ( SELECT userid, user_id, GROUP_CONCAT( cat_id ) AS cat_id FROM user_cat WHERE userid='$user_id' GROUP BY user_id ) AS d ON d.userid='$user_id' AND d.user_id=a.userid
WHERE a.cat != ? ORDER BY a.date desc";