I have a query that produces 3 columns (ApplicationID, FamilySize, GrantID). In the initial query FamilySize is a count. The query works, takes about 5 minutes to produce results, and produces expected results. The query is as such:
SELECT t1.ApplicationID, COUNT(*) FamilySize, t1.GrantID
FROM
(
SELECT g.ApplicationID, ChildApplicationID `RefID`, g.GrantID
FROM CONTINUITYCHILD_P `child`
JOIN uspto.GRANT as g ON child.ApplicationID = g.ApplicationID
UNION
SELECT g2.ApplicationID, ParentApplicationID `RefID`, g2.GrantID
FROM CONTINUITYPARENT_P `par`
JOIN uspto.GRANT as g2 ON par.ApplicationID = g2.ApplicationID
) t1
GROUP BY ApplicationID
That initial query works fine. However, I want to use it to update a field in another table Where the GrantID match. I'm using MariaDB but looked at the MySQL 8 documentation since MariaDB and MySQL are supposed to have compatible syntax: https://dev.mysql.com/doc/refman/8.0/en/update.html
I am trying to use the syntax similar to this:
UPDATE t1, t2
SET t1.column = t2.column
WHERE t1.column2 = t2.column2
So that would convert my entire initial query into a table (t2) and the table being updated (t1) would be able to match on a column between t1 and t2.
This is the resulting query:
UPDATE METRICS_G m,
(
SELECT ApplicationID, COUNT(*) FamilySize, GrantID
FROM
(
SELECT g.ApplicationID, ChildApplicationID `RefID`, g.GrantID
FROM CONTINUITYCHILD_P `child`
JOIN uspto.GRANT as g ON child.ApplicationID = g.ApplicationID
UNION
SELECT g2.ApplicationID, ParentApplicationID `RefID`, g2.GrantID
FROM CONTINUITYPARENT_P `par`
JOIN uspto.GRANT as g2 ON par.ApplicationID = g2.ApplicationID
) t1
GROUP BY ApplicationID
) t2
SET m.FamilySize = t2.FamilySize
WHERE m.GrantID = t2.GrantID;
The query gives no errors, and returns in 3ms with 0 rows affected.
This must mean that the sub-query is not being executed since it will normally take a few minutes for that query to return.
What have I done wrong to use the output of a query as a table to match in an UPDATE statement?
You must join the query to the table METRICS_G in the UPDATE statement:
UPDATE METRICS_G m
INNER JOIN (
SELECT ApplicationID, COUNT(*) FamilySize, GrantID
FROM (
SELECT g.ApplicationID, ChildApplicationID `RefID`, g.GrantID
FROM CONTINUITYCHILD_P `child`
JOIN uspto.GRANT as g ON child.ApplicationID = g.ApplicationID
UNION
SELECT g2.ApplicationID, ParentApplicationID `RefID`, g2.GrantID
FROM CONTINUITYPARENT_P `par`
JOIN uspto.GRANT as g2 ON par.ApplicationID = g2.ApplicationID
) t1
GROUP BY ApplicationID
) t2 ON m.GrantID = t2.GrantID
SET m.FamilySize = t2.FamilySize
Related
I am trying to merge the rows based on condition in mysql.
I have table as shown below :
Looking merge the row 1 into row 2 (where the attendance count is larger)
and need to shown the result as :
I was trying to divide the dataset into 2 parts using the below query
select
a.student_id,a.school_id,a.name,a.grant,a.classification,a.original_classification,,a.consent_type
from (
select * from school_temp where original_classification='all' and availability='implicit')a
join(select * from school_temp where original_classification!='all' and availability!='implicit')b
on a.student_id = b.student_id and a.school_id=b.school_id and a.name=b.name
But unable to merge the rows and get total attendance count .
Please help me ,i am badly stuck in this
Split this into two queries that you combine with UNION.
The first joins the implicit row with the row with the highest attendance among the explicit rows for each student. See Retrieving the last record in each group - MySQL for how that works. Use SUM(attendance_count) to combine the attendances.
The second query in the UNION gets all the rows that don't have the highest attendance.
WITH explicit as (
SELECT *
FROM school_temp
WHERE original_classification!='all' and availability!='implicit'
)
SELECT a.student_id, a.school_id, a.name, SUM(attendance_count) AS attendance_count,
b.grant, b.classification, b.original_classification, b.consent_type
FROM school_temp AS a
JOIN (
SELECT t1.*
FROM explicit AS t1
JOIN (
SELECT student_id, school_id, name, MAX(attendance_count) AS max_attendance
FROM explicit AS t2
GROUP BY student_id, school_id, name
) AS t2 ON t1.student_id = t2.student_id AND t1.school_id = t2.school_id AND t1.name = t2.name AND t1.attendance_count = t2.max_attendance
) AS b ON a.student_id = b.student_id and a.school_id=b.school_id and a.name=b.name
WHERE a.original_classication = 'all' AND a.availability = 'implicit'
UNION ALL
SELECT t1.*
FROM explicit AS t1
JOIN (
SELECT student_id, school_id, name, MAX(attendance_count) AS max_attendance
FROM explicit AS t2
GROUP BY student_id, school_id, name
) AS t2 ON t1.student_id = t2.student_id AND t1.school_id = t2.school_id AND t1.name = t2.name AND t1.attendance_count < t2.max_attendance
I've used a CTE to give a name to the subquery that gets all the explicit rows. If you're using MySQL 5.x, you'll need to replace explicit with that subquery throughout the query. Or you could define it as a view.
In MS Access:
I am trying to compare two tables with:
- TABLE1.docnumb1 = TABLE2.docnumb2
- looking for: TABLE1.sum <> TABLE2.sum2
But query retrieves an error: syntax error in from clause (or when creating left join I get an error that JOIN isn't supported):
SELECT docnumb1, sum
FROM Table1
JOIN Table2 ON docnumb1 = docnumb2;
How do I query the rows with different values?
looking to your sample (image)
you could compare the subquery for sum
select t1.rownumb, t1.sum1 -t2.sum2
from (
SELECT rownumb, sum(value) sum1
FROM Table1
group by rownumb
) t1
INNER JOIN
(
SELECT rownumb, sum(value) sum2
FROM Table2
group by rownumb
) t2 ON t1.rownumb = t2.rownumb and (t1.sum1 -t2.sum2 ) <> 0
use left join
SELECT docnumb1, sum
FROM Table1 a
left JOIN Table2 b ON a.docnumb1 = b.docnumb2 and a.value=b.value
where b.docnumb2 is null
I have a weird situation. I need to select all data from table name with distinct values from other table.
Here is database scheme of database that I need to get distinct values:
When I run both queries without INNER JOIN they run without error but when I use INNER JOIN I got error
This is query that I used:
SELECT * FROM `todo`
INNER JOIN
SELECT `task`.`status`,COUNT(*) as count FROM `task`
ON `todo`.`id`=`task`.`id_list` WHERE `todo`.`user_id` = 43
As you can see I need to get total count of status column from other table. Can it be done using one single query or do I need to run two querys to get data...
You need to wrap the join In parenthesis
SELECT td.*, t.*
FROM `todo` td
JOIN
( SELECT `status`, SUM(status=0) as status_0, SUM(status=1) as status_1 , id_list
FROM `task`
GROUP BY id_list
) t ON td.id= t.id_list
WHERE td.user_id = 43
You can do this in one query. Even without a subquery:
SELECT ta.status, COUNT(*) as count
FROM todo t INNER JOIN
task ta
ON t.id = ta.id_list
WHERE t.user_id = 43
GROUP BY ta.status;
EDIT:
If the above produces what you want, then you probably need:
SELECT t.*, ta.status, taa.cnt
FROM todo t INNER JOIN
task ta
ON t.id = ta.id_list INNER JOIN
(SELECT count(*) as cnt, ta.status
FROM task ta
GROUP BY ta.status
) taa
on ta.status = taa.status
WHERE t.user_id = 43 ;
You seem to want a summary at the status level, which is only in task. But you want the information at the row level for todo.
In my system I want to get attendance data of employee from the DB, so I wrote a huge SQL query, and it gives me relevant details. But now I need an updated version of particular results. So I don’t know how to put this query within the update statement.
select * from(
select concat('pre:', date) as date,concat('pre:',employee_no) as employee_no,concat('pre:',name_with_initials) as name,concat('pre:',sign_in_at) as sign_in_at,concat('pre:',sign_out_at) as sign_out_at,emp from( SELECT date, present.employee_no,employee_details.name_with_initials,present.sign_in_at, present.sign_out_at,employee_details.employee_no as emp from (
SELECT employee_no,date,sign_in_at,sign_out_at FROM complete_shifts WHERE date = '2013-06-17' UNION ALL
SELECT employee_no,date,sign_in_at,'00:00:00 ' AS sign_out_at FROM incomplete_shifts WHERE date = '2013-06-17' UNION ALL
SELECT employee_no,date,sign_in_at,'00:00:00 ' AS sign_out_at FROM incomplete_shift_records WHERE date = '2013-06-17'
)as present inner join employee_details on present.employee_no = employee_details.employee_no
) as final_present
union all
select concat('ab:',date)as date,concat('ab:',employee_no)as employee_no,concat('ab:',name_with_initials)as name,concat('ab:',sign_in_at)as sign_in_at,concat('ab:',sign_out_at)as sign_out_at, emp from(
select '2013-06-17' AS date,absent.employee_no,employee_details.name_with_initials,'00:00:00'as sign_in_at , '00:00:00' as sign_out_at,employee_details.employee_no as emp from (
select * from ( SELECT employee_details.employee_no FROM employee_details left outer join resigned_emps on
employee_details.employee_no = resigned_emps.employee_no where resigned_emps.date is null or resigned_emps.date>'2013-06-17'
) as available_emps left outer join (
select employee_no from complete_shifts where date = '2013-06-17' union
select employee_no from incomplete_shifts where date = '2013-06-17' union
select employee_no from incomplete_shift_records where date = '2013-06-17'
) as present on available_emps.employee_no = present.employee_no where present.employee_no is null
) as absent inner join employee_details on absent.employee_no = employee_details.employee_no
) as final_absent
)as final left outer join( SELECT leave.employee_no as lv_emp
FROM leave_dates inner join leave on leave_dates.leave_id = leave.leave_id where leave_dates.date = '2013-06-17')as leave_emps
on final.emp = leave_emps.lv_emp;
With such a large query, you should just put the results in a temporary table and update from that.
create temporary table toupdate as
<your query goes here>;
Now you can investigate the data that will be updated, to be sure that it really is ok.
Next you can do the update as a join:
update table_to_update t join
toupdate
on t.key = toupdate.key
set t.col = toupdate.col
Because you don't give the column or table details, this is just the structure of such a solution.
Instead of "select *", use the appropriate unique field to fetch the records to update, ex EmpID. Finally use this result as inner query result to update query.
Example
Update ... set ... where empid in (your select query goes here)
I have this query:
SELECT t1.* FROM table t1
JOIN
(
SELECT MIN(orig_id) min_orig_id, MAX(orig_id) max_orig_id
FROM table
GROUP BY left(datetime,4), mid(datetime,5,2),
mid(datetime,7,2), mid(datetime,10,2), mid(datetime,13,2)
) t2
ON t1.orig_id = t2.min_orig_id OR t1.orig_id = t2.max_orig_id;
It groups records by first & last record in each minute.
Now I want to group by first & last record in each 3 minutes.
Any idea?
Thanks
This might be what you're looking for
SELECT t1.* FROM table t1
JOIN
(
SELECT MIN(orig_id) min_orig_id, MAX(orig_id) max_orig_id
FROM table
GROUP BY concat(left(datetime,4), mid(datetime,5,2),
mid(datetime,7,2), mid(datetime,10,2),(cast mid(datetime,13,2) as integer)/3)
) t2
ON t1.orig_id = t2.min_orig_id OR t1.orig_id = t2.max_orig_id;
If datetime is a timestamp/datetime data type and not a string
SELECT t1.* FROM table t1
JOIN
(
SELECT MIN(orig_id) min_orig_id, MAX(orig_id) max_orig_id
FROM table
GROUP BY UNIX_TIMESTAMP(datetime)/3
) t2
ON t1.orig_id = t2.min_orig_id OR t1.orig_id = t2.max_orig_id;
is much cleaner