Distinct SUM with Mysql Count - mysql

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.

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;

Get id of the record having Min() value

I have a complex mysql query where one of the Select fields is Min(value). Since all the 'values' are unique, is there also a way to get found min value's row id along?
In other words if we simplify the query to this question, it is like this:
SELECT t1.name, MIN(t2.value) AS minval
FROM table1 t1
LEFT JOIN table2 t2
ON t2.id_user = t1.id
GROUP BY id_user
How can i now know which t2.id was chosen for lowest t2.value for particular user? Thank you!
Use ROW_NUMBER() to find the first value of each id_user
You can replace * with the fields you need
SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY t2.id_user ORDER BY t2.value) as rnk
FROM table1 t1
LEFT JOIN table2 t2
ON t2.id_user = t1.id
) as X
WHERE X.rnk = 1
Maybe this simple, dont know how complex your statement is:
SELECT name,value,id
FROM(
SELECT t1.name,t2.value,t2.id
FROM table1 t1
LEFT JOIN table2 t2
ON t2.id_user = t1.id
GROUP BY t2.id,id_user
ORDER BY t1.name,t2.id asc) as test
GROUP BY name;

GROUP CONCAT with sum function

I want to concat the total of my sum function, please help me, Thanks
This is my query:
SELECT t1.province, t2.fullname,sum(t1.total_vote) AS total
FROM votes AS t1, candidate AS t2
WHERE t1.candidate_id = t2.id
GROUP BY t2.id, t1.province
ORDER BY t2.id
So just use concat. (And an inner join would be neater.)
SELECT concat(t2.fullname, ' has ', sum(t1.total_vote), ' votes in ', t1.province, '.') AS concatinated_line
FROM votes AS t1
INNER JOIN candidate AS t2 ON t1.candidate_id = t2.id
GROUP BY t2.id, t1.province
ORDER BY t2.id
The above answer should be correct, just add a closing parens in the SELECT:
SELECT concat(t2.fullname, ' has ', sum(t1.total_vote), ' votes in ', t1.province, '.') AS concatinated_line
FROM votes AS t1
INNER JOIN candidate AS t2 ON t1.candidate_id = t2.id
GROUP BY t2.id, t1.province
ORDER BY t2.id
Try this:
SELECT fullname , GROUP_CONCAT(cast(total as char))
FROM
(
SELECT t2.fullname fullname,sum(t1.total_vote) AS total
FROM votes AS t1, candidate AS t2
WHERE t1.candidate_id = t2.id
GROUP BY t2.id, t1.province
ORDER BY t2.id
) s

Select from table using resolute from another query

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

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