mysql query migrating away from sub query - mysql

Hi I have the following working query, but I'm looking to move away from the sub query approach.
select t0.emp_id, t1.first_name, t1.last_name
from employee_profile As t0 left join user_profile as t1 on t0.user_profile_id = t1.id
where t0.emp_id not in (select t4.emp_id from time_sheet as t4 where t4.ts_end_date = '2014-10-08')
There is 1301 employee profiles
There is 337 that do not have time_sheets for end date 2014-10-08
This works perfectly thus far.
Now I'm trying to migrate away from the sub query and into a join. I've tried the following without success.
With this query, I get the complete opposite of what I'm looking for which is 964 results.
select t0.emp_id, t1.first_name, t1.last_name, t3.emp_id
from employee_profile As t0 left join user_profile as t1 on t0.user_profile_id = t1.id
left join time_sheet as t3 on t0.id = t3.employee_profile_id
I've also tried the following using where conditions and got 0 results
1.
where t3.ts_end_date = '2014-10-08'
and t3.employee_profile_id is null
2.
where t3.ts_end_date = '2014-10-08'
and t3.id is null
Does anybody know how to fix this?

Figured it out
select t0.emp_id, t1.first_name, t1.last_name, t3.emp_id
from employee_profile As t0 left join user_profile as t1 on t0.user_profile_id = t1.id
left join time_sheet as t3 on t0.id = t3.employee_profile_id and t3.ts_end_date = '2014-10-08'
where t3.employee_profile_id is null

Related

Update several select in MySQL

It's a sample to see the result.
Hello Everyone,
I wrote a query as a sample and I used several selects because I needed to add columns separately.
So, I got the result.
now I want to know if can I use an update statement for this query?
select T3.*,ao_00b950_aoproject_value.VALUE ODP from
(select T2.*,ao_00b950_aoproject_value.VALUE SOD from
(select T1.*,ao_00b950_aoproject_value.VALUE Platform from (SELECT project.LEAD,project.id,project.pname,project.pkey,ao_00b950_aoproject_value.VALUE Status FROM jira820db.project
LEFT JOIN jira820db.ao_00b950_aoproject_value
on project.ID=ao_00b950_aoproject_value.PROJECT_ID
and ao_00b950_aoproject_value.FIELD_ID =1) as T1
left join ao_00b950_aoproject_value
on T1.ID = ao_00b950_aoproject_value.project_ID
and ao_00b950_aoproject_value.field_ID=26) as T2
left join ao_00b950_aoproject_value
on T2.ID = ao_00b950_aoproject_value.project_ID
and ao_00b950_aoproject_value.field_ID=28) as T3
left join ao_00b950_aoproject_value
on T3.ID = ao_00b950_aoproject_value.project_ID
and ao_00b950_aoproject_value.field_ID=27
So, I wrote this update statement:
update
(select T3.*,ao_00b950_aoproject_value.VALUE ODP from
(select T2.*,ao_00b950_aoproject_value.VALUE SOD from
(select T1.*,ao_00b950_aoproject_value.VALUE Platform from (SELECT project.LEAD,project.id,project.pname,project.pkey,ao_00b950_aoproject_value.VALUE Status FROM jira820db.project
LEFT JOIN jira820db.ao_00b950_aoproject_value
on project.ID=ao_00b950_aoproject_value.PROJECT_ID
and ao_00b950_aoproject_value.FIELD_ID =1) as T1
left join ao_00b950_aoproject_value
on T1.ID = ao_00b950_aoproject_value.project_ID
and ao_00b950_aoproject_value.field_ID=26) as T2
left join ao_00b950_aoproject_value
on T2.ID = ao_00b950_aoproject_value.project_ID
and ao_00b950_aoproject_value.field_ID=28) as T3
left join ao_00b950_aoproject_value
on T3.ID = ao_00b950_aoproject_value.project_ID
and ao_00b950_aoproject_value.field_ID=27) as ww
set project.LEAD = 'kami'
where project.ID ='10000';
But unfortunately, it's not working and I'm not surprised because I'm not an expert in MySQL.
Does anybody have any suggestions?
Or I'm writing wrong the code like always.
With the first query, I get my result, and run perfectly.
With the second one, I get an error code 1288 "The target table ww of the UPDATE is not updatable".

Calculating SUM() results from subqueries into a total

My brain is starting to hurt with this query and I would appreciate some guidance. What I am trying to get as the result of this query are three values: attendanceScore, lootScore, and totalScore (attendanceScore - lootScore).
Attendance is tracked across three tables: attendance, attendancelog, and attendancevalues.
attendance records an individual's attendance status attached to an attendancelog record. There are types of attendance such as "attended", "missed", and "called out".
attendancelog is the parent record which records the event type, title and date as well as who logged the attendance and when.
attendancevalues is a config table that matches the attendance type from attendance and the event type from attendancelog and returns a configurable value FLOAT.
Loot is tracked across two tables: loot and loottypes.
loot logs each individual item, who received it and when and what type of loot it was (Primary, Secondary, Free-for-all).
loottypes is a config table that takes the type from loot and returns a configurable cost FLOAT.
After some work I have come up with a working query to get attendanceScore and lootScore:
SELECT
(SELECT SUM(t3.`value`)
FROM `attendance` t1
INNER JOIN `attendancelog` t2
ON t2.`id` = t1.`attendancelog_id`
INNER JOIN `attendancevalues` t3
ON t3.`eventtype_id` = t2.`type` AND t3.`attendancetype_id` = t1.`type`
WHERE t1.`user_id` = 3) as attendanceScore,
(SELECT SUM(t2.`cost`)
FROM `loot` t1
INNER JOIN `loottypes` t2
ON t2.`id` = t1.`type`
WHERE t1.`user_id` = 3) as lootScore
I know this doesn't work, but I tried to add (attendanceScore - lootScore) to the query but it says those fields are not available. That is ultimately what I need to complete the query.
I can get the result I want by copying each of the subqueries directly into (attendanceScore - lootScore) but it is just absolutely hideous and I'm sure unnecessary:
SELECT
(SELECT SUM(t3.`value`)
FROM `attendance` t1
INNER JOIN `attendancelog` t2
ON t2.`id` = t1.`attendancelog_id`
INNER JOIN `attendancevalues` t3
ON t3.`eventtype_id` = t2.`type` AND t3.`attendancetype_id` = t1.`type`
WHERE t1.`user_id` = 3) as attendanceScore,
(SELECT SUM(t2.`cost`)
FROM `loot` t1
INNER JOIN `loottypes` t2
ON t2.`id` = t1.`type`
WHERE t1.`user_id` = 3) as lootScore,
(
(SELECT SUM(t3.`value`)
FROM `attendance` t1
INNER JOIN `attendancelog` t2
ON t2.`id` = t1.`attendancelog_id`
INNER JOIN `attendancevalues` t3
ON t3.`eventtype_id` = t2.`type` AND t3.`attendancetype_id` = t1.`type`
WHERE t1.`user_id` = 3) - (SELECT SUM(t2.`cost`)
FROM `loot` t1
INNER JOIN `loottypes` t2
ON t2.`id` = t1.`type`
WHERE t1.`user_id` = 3)
) as totalScore
Could someone help me understand what methods to use for cleaning this up into something more streamlined and efficient?
You may use an inline view
SELECT attendanceScore,
lootScore,
attendanceScore - lootScore as totalScore
FROM
(
SELECT
(
SELECT SUM(t3.`value`)
FROM `attendance` t1
INNER JOIN `attendancelog` t2
ON t2.`id` = t1.`attendancelog_id`
INNER JOIN `attendancevalues` t3
ON t3.`eventtype_id` = t2.`type` AND t3.`attendancetype_id` = t1.`type`
WHERE t1.`user_id` = 3
) as attendanceScore,
(
SELECT SUM(t2.`cost`)
FROM `loot` t1
INNER JOIN `loottypes` t2 ON t2.`id` = t1.`type`
WHERE t1.`user_id` = 3) as lootScore
) t

Creating an update statement from a nested select

I have a mysql statement below
select c11 as genre, t3.strGenre, t2.idGenre t2idGenre, t1.idMVideo
from musicvideo t1
join genrelinkmusicvideo t2
on t2.idMVideo=t1.idMVideo
join genre t3
on t3.idGenre=t2.idGenre
where not (c11=strGenre) and genre='Alternative Rock'
This works fine and gives me the desired results.
Now when I want to put this into an update statement i get stuck.
update t2
set idGenre=62
where (select c11, t3.strGenre, t2.idGenre t2idGenre
from musicvideo t1
join genrelinkmusicvideo t2
on t2.idMVideo=t1.idMVideo
join genre t3
on t3.idGenre=t2.idGenre
where not (c11=strGenre) and genre='Alternative Rock')
I know this is not correct. Any help would be appreciated.
Try:
update genrelinkmusicvideo t2
join musicvideo t1
on t2.idMVideo = t1.idMVideo
join genre t3
on t3.idGenre = t2.idGenre
set t2.idGenre = 62
where c11 <> strGenre and genre = 'Alternative Rock'
FYI, I would recommend using table_alias.column (e.g. t3.genre = 'Alternative Rock'), since it makes thing much more clear, particularly for those who do not know the schema already.
You could try:
update genrelinkmusicvideo
set idGenre=62
where idGenre IN (select t2.idGenre
from musicvideo t1
join genrelinkmusicvideo t2
on t2.idMVideo=t1.idMVideo
join genre t3
on t3.idGenre=t2.idGenre
where not (c11=strGenre) and genre='Alternative Rock')

simple mysql query count fails

SELECT
count(t1.id) AS c1
FROM
table2
LEFT JOIN table1 AS t1 ON (t1.uid = table2.uid)
WHERE
table2.mode = 'ls'
GROUP BY
t1.id
c1 = 6 -> CORRECT!
SELECT
count(t2.id) AS c2
FROM
table2
LEFT JOIN table1 AS t2 ON (t2.pid = table2.id)
WHERE
table2.mode = 'ls'
GROUP BY
t1.id
c2 = 1 -> CORRECT!
SELECT
count(t1.id) AS c1,
count(t2.id) AS c2
FROM
table2
LEFT JOIN table1 AS t1 ON (t1.uid = table2.uid)
LEFT JOIN table1 AS t2 ON (t2.pid = table2.id)
WHERE
table2.mode = 'ls'
GROUP BY
t1.id
c1 = 6 -> CORRECT!
c2 = 6 -> WRONG!
How do I request both counts in one query, without getting wrong results?
I need to count two different requests at the same table (table1).
so, I'm using an alias for both request. (t1). Each alias-request is working fine alone. If I use both in the same query, i got wrong results.
count() will get you the number of records that are returned by your query. Since if you removed the counts and replaced it with * you would have 6 rows both of those counts are giving you 6.
Is there any reason why you cant use two sub selects and return the result of each of those?
So:
SELECT subQ1.c1, subQ2.c2 FROM
(SELECT count(t1.id) AS c1 FROM table2
LEFT JOIN table1 AS t1 ON (t1.uid = table2.uid)
WHERE table2.mode = 'ls') as subQ1,
(SELECT count(t2.id) AS c2 FROM table2
LEFT JOIN table1 AS t2 ON (t2.pid = table2.id)
WHERE table2.mode = 'ls') as SubQ2;
I believe your problem on the full query is your group by function. You are grouping by t.id, thus a1.id will have a different count based on how many rows you have.
What I mean by this is if there are 6 rows in table t, then count is going to return 6 for table t; but also since there looks to be a 1 to 1 relation on table a, there are 6 matching rows in table a to the 6 matching rows in table t. such that
t.id = a.id
1 = 1
2= 2 ...etc.
Thus your count is returning rows versus the count you believe you should have? I believe sum function is what you want to use here.
You could try this...but I'm not really sure what you're trying to do.
SELECT (...)
count(CASE WHEN t1.uid = t3.uid THEN t1.id ELSE NULL END) AS CBanz,
count(CASE WHEN ta1.pid = t3.id THEN a1.id ELSE NULL END) AS CBanz1
FROM
t0
LEFT JOIN (...)
LEFT JOIN t1 ON (t1.uid = t3.uid)
LEFT JOIN t1 AS a1 ON (a1.pid = t3.id)
WHERE (...)

MySql: merge three tables together

I want to merge three tables together as shown here:
Basically I want to include the items from all three tables T1, T2 and T3 and have them merged as shown in the result table. I tried something like this:
SELECT T1.user, T2.tid, T2.name, T3.type, T1.mid
FROM T1
LEFT JOIN T2 ON T1.mid = T2.mid
LEFT JOIN T3 ON T2.tid = T3.tid
GROUP BY T1.user;
But it does not seem to have worked. It does show the results but only unique values. In the result if user is johny, it will only show the first value and ignore the second, though it should be in the result table.
Is there something I am missing?
The Group is not necessary if you want to see all results for each of the users. Otherwise it will hide some of the rows and show just one per user.
First join T1 Right to T2 than Left Join to T3. This is good practice if there is element from T1 that has no connection with element from T3 to prevent showing NULL result for T£ fields.
SELECT T1.user, T2.tid, T2.name, T3.type, T1.mid
FROM T1
RIGHT JOIN T2 ON T1.mid = T2.mid
LEFT JOIN T3 ON T2.tid = T3.tid;
Get rid of the "Group By" part. This should fix your problem.
Eliminate the GROUP BY. There's no need for it in this query.
SELECT T1.user, T2.tid, T2.name, T3.type, T1.mid
FROM T1
LEFT JOIN T2 ON T1.mid = T2.mid
LEFT JOIN T3 ON T2.tid = T3.tid;