Select from table using resolute from another query - mysql

You see, t1 and t2 have some similar rows, on the first query I select the ones that don't match, I used the following Query
SELECT DISTINCT t1.usr_id
FROM t1, t2
WHERE t1.usr_id != t2.usr_id
AND t1.event = '$event'
AND t1.client = '$client'
GROUP BY t1.usr_id
Now I want to use the result from the query above to select * from t3 matching usr_id.
I'v tried the answers given to other almost similar questions but none of them is subtracting from one query and using results to obtain data from a second query

Try this:
SELECT t3.usr_id FROM t3 WHERE t3.usr_id IN
(SELECT DISTINCT t1.usr_id
FROM t1, t2
WHERE t1.usr_id != t2.usr_id
AND t1.event = '$event'
AND t1.client = '$client'
GROUP BY t1.usr_id)
but it may be slow, than:
SELECT table.usr_id
FROM ( SELECT DISTINCT t1.usr_id
FROM t1, t2
WHERE t1.usr_id != t2.usr_id
AND t1.event = '$event'
AND t1.client = '$client'
GROUP BY t1.usr_id ) as table
JOIN t3 ON t3.usr_id = table.usr_id

Related

Join with column outside subquery

SELECT t1.name as r_name, t1.values as r_values
FROM table as t1
JOIN (
SELECT SUM(amount) as amount
FROM database2.table
WHERE ids IN (t1.values)
) as t2
WHERE t1.id = 20;
I get an error, that t1.values inside the subquery is unknown column.
You need to rewrite your query and take inne where to join condition:
SELECT t1.name as r_name, t1.values as r_values
FROM table as t1
JOIN (
SELECT SUM(amount) as amount
FROM database2.table
) as t2 ON t2.ids = t1.values
WHERE t1.id = 20;
Also, you don't use amount column, so what is the point of join?
Another issue, you don't have any join condition defined.
I think you need to read about joins in SQL first :)
It seems you are trying to join database2.table to your t1 based on t1.values list.
I added group by IDs in t2 since your using aggregation function. Then, not sure what's the purpose of your sum(amount)
SELECT t1.name as r_name, t1.values as r_values
FROM table as t1
JOIN (
SELECT SUM(amount) as amount, ids
FROM database2.table
GROUP BY ids
) as t2 on t2.ids IN (t1.values)
WHERE t1.id = 20;

MySQL writing join on three tables

I have written the following mysql query
SELECT distinct name, date
FROM table1
JOIN table2 ON (table2.item_id = table1.item_id)
where table1.id IN (SELECT run_id FROM
table3 where table3.status = 'FAIL') and table1.createdate >= '2011-01-01'
;
I want to include another field message from table3 in my output.
I guess this might involve joining 3 tables in the query.
Please let me know how to achieve this.
There's not quite enough info to fully answer the question. We also want to know:
Does the status column come from table1 or from table3
Can there be more than one table3 record with a runid that matches a table1.id value?
If there can be, which table3.message value do you want to show?
Without knowing that info, all we can do is guess. Here is my guess:
SELECT distinct name, date, message
FROM table1 t1
INNER JOIN table2 t2 ON t2.item_id = t1.item_id
INNER JOIN table3 t3 on t1.id =t3.run_id AND t3.status = 'FAIL'
WHERE t1.createdate >= '2011-01-01'
Try this :-
SELECT DISTINCT T1.NAME , T1.DATE , T3.MESSAGE
FROM TABLE1 T1
JOIN TABLE2 T2
ON
T1.ITEM_ID = T2.ITEM_ID
INNER JOIN TABLE3 T3
ON
T1.ID = T3.RUN_ID
WHERE T3.STATUS = 'FAIL' AND T1.CREATEDATE >= '2011-01-01';
Try this
SELECT distinct name, date, T3.message
FROM table1
JOIN table2 ON (table2.item_id = table1.item_id)
INNER JOIN (SELECT run_id FROM
table3 where status = 'FAIL') T3 ON T3.run_id = table1.id
where table1.createdate >= '2011-01-01'
try this :
select distinct name,date, message from table1 t1,table2 t2,table3 t3 where t1.item_id = t2.item_id and t1.item_id = t3.item_id
and t3.status ='FAIL' AND t1.createdate >= to_date('2011-01-01,'YYYY-DD-MM');

MySQL Update using INNER JOIN with ORDER BY and LIMIT

I'm trying to do an update using an inner join with limit and order by (although the order by is not essential. From what I have read up the standard update will not work... this is what I am trying to do:
UPDATE table1
INNER JOIN table2
ON table1.service_id=table2.service_id
SET table1.flags = NULL
WHERE table1.type = 'fttc'
AND table1.flags = 'co'
AND table2.sync not like '%Yes%'
AND table1.date >= $today_date
ORDER BY table1.priority ASC
LIMIT 20;
it is for use in a case management tool and using php, I want to update 20 tickets i.e. remove the 'flag' so that they can be worked, the quantity will be passed as a variable, so I want to update 20 tickets for example highest 'priority' first, if that can be done?
If I read your question correctly, you want to perform an update on the first 20 records which results from the join, using the priority as ordering. You cannot do this directly in an UPDATE in MySQL AFAIK, but you can create an updatable view and then update that.
CREATE VIEW yourView
AS
SELECT
t1.service_id,
t2.service_id,
t1.flags,
t1.type,
t1.date,
t1.priority,
t2.sync
FROM table1 t1
INNER JOIN table2 t2
ON t1.service_id = t2.service_id
WHERE t1.type = 'fttc' AND
t1.flags = 'co' AND
t2.sync NOT LIKE '%Yes%' AND
t1.date >= $today_date
ORDER BY t1.priority
LIMIT 20;
And then update this view:
UPDATE yourView
SET flags = NULL
There should be no reason to use a view:
UPDATE table1 t1
SET t1.flags = NULL
WHERE t1.type = 'fttc' AND
t1.flags = 'co' AND
t1.date >= $today_date AND
EXISTS (SELECT 1
FROM table2 t2
WHERE t2.service_id = t1.service_id AND
t2.sync not like '%Yes%'
)
ORDER BY t1.priority ASC
LIMIT 20;
You cannot use ORDER BY and LIMIT with a multiple table JOIN. However, you can move the condition on table2 to the WHERE clause.
Following work for me:
UPDATE child AS upd
JOIN (SELECT t1.id FROM child AS t1
INNER JOIN master AS t2
ON t2.id = t1.id
where 1
AND t2.`date` BETWEEN '2020-06-23 00:00:00' AND '2020-06-23 23:59:59'
AND t2.client_id= 10 AND t1.code NOT IN('11','22')
order by t1.id desc LIMIT 1) AS col
ON upd.id=col.id
SET upd.code= '33', upd.`resp` = 'done',upd.status='success'

Distinct SUM with Mysql Count

I have a query:
SELECT
t1.name as Name
count ( distinct t2.key ) as Total
SUM ( IF( t2.time = '12:00' , 1 , 0) ) as QttMidDay
FROM t1
LEFT JOIN t2 on t1.key = t2.key
GROUP BY t1.key
The question is, how i do the "Conditional Count" on the 2ยบ parameter SUM for QttMidDay ?
I am guessing that you can solve your problem by aggregating before the join. My best guess is:
SELECT t1.name as Name, t2.Total, t2.QttMidDay
FROM t1 LEFT JOIN
(SELECT COUNT(DISTINCT t2.key) as Total,
SUM(t2.time = '12:00') as QttMidDay
FROM t2
GROUP BY t2.key
) t2
ON t1.key = t2.key;
I am not sure if the COUNT(DISTINCT) is necessary in the subquery.

Multiple aggregate functions in MySQL with different conditions

I am running the following query
SELECT t2.lender_name, COUNT(t1.id) as total,
SUM(t1.submit_date IS NULL) AS num_incomplete,
(SELECT AVG(DATEDIFF(due_date,now()))
FROM table_1 WHERE submit_date IS NULL ) as avg_incomplete_due_in,
(SELECT AVG(DATEDIFF(due_date,submit_date))
FROM table_1 WHERE submit_date IS NOT NULL) as avg_complete_turnaround
FROM table_1
INNER JOIN table_2 t2 ON t2.fid = t1.id
WHERE t1.due_date <= '2010-12-31'
GROUP BY t2.lender_name
The total, num_incomplete and the grouping works great. The sub select values are the same for each row. I would like those values grouped by the lender_name also and returned as part of the same recordset. Any suggestions?
Your current code just lacks a relation between the outer query and the subqueries. In theory, you just need to correlate the queries:
SELECT t2.lender_name, COUNT(t1.id) as total,
SUM(t1.submit_date IS NULL) AS num_incomplete,
(SELECT AVG(DATEDIFF(due_date,now()))
FROM table_1 t3
WHERE submit_date IS NULL
AND t3.lender_name = t2.lender_name) as avg_incomplete_due_in,
(SELECT AVG(DATEDIFF(due_date,submit_date))
FROM table_1
WHERE submit_date IS NOT NULL
AND t3.lender_name = t2.lender_name) as avg_complete_turnaround
FROM table_1 t1
INNER JOIN table_2 t2 ON t2.fid = t1.id
WHERE t1.due_date <= '2010-12-31'
GROUP BY t2.lender_name
In practice, the query is not very efficient in MySQL. You can rewrite it in the following way:
SELECT
t2.lender_name,
COUNT(*) as total,
SUM(t1.submit_date IS NULL) AS num_incomplete,
AVG(IF(t1.submit_date IS NULL,
DATEDIFF(t1.due_date, NOW()),
NULL)) AS avg_incomplete_due_in,
AVG(DATEDIFF(due_date,submit_date)) AS avg_complete_turnaround
FROM table_1 t1
INNER JOIN table_2 t2 ON t2.fid = t1.id
WHERE t1.due_date <= '2010-12-31'
GROUP BY t2.lender_name
sum if, and count if do the trick
SELECT t2.lender_name, COUNT(t1.id) as total,
SUM(t1.submit_date IS NULL) AS num_incomplete,
SUM(IF(table_1.submit_date IS NULL,DATEDIFF(table_1.due_date,now()),0)) / COUNT(IF(table_1.submit_date IS NULL,1,NULL)) as avg_incomplete_due_in
SUM(IF(table_1.submit_date IS NOT NULL,DATEDIFF(table_1.due_date,submit_date),0)) / COUNT(IF(table_1.submit_date IS NOT NULL,1,NULL)) as avg_complete_turnaround
FROM table_1
INNER JOIN table_2 t2 ON t2.fid = t1.id
WHERE t1.due_date <= '2010-12-31'
GROUP BY t2.lender_name