using the result of subquery in mysql - mysql

how can i use the result of a subquery inside its parent query?
my code look like this.
select (select count(*) from tbl1 group by field) as result1,
(select count(*) from tbl2 group by field) as result2,
(select count(*) from tbl3 group by field) as result3,
result1 + result2 - result3 as total1,
result1 + result2 as total2
from tbl4 ;
some suggest to direct add the subquery .
(select count(*)*....) as result1 + (select count(*)*....) as result2
but i think its not want i need, bcoz i need also to display/maintain the value of result1 in my result.
is there somebody who can help me, i badly need this to work out, i appreciate every help.
thanks in advance.

Suppose your sub query will return a set. So just use the following---
SELECT column1, column2, column3
FROM table1
WHERE column3 IN (SELECT column3
FROM table2 WHERE condition);

select count1, count2, count3,
count1+count2-count3 as total1, count1+count2 as total2
from tbl4
inner join
(select count(*) as count1,name from tbl1 group by name)as result1
on tbl4.name=result1.name
inner join
(select count(*)as count2,name from tbl2 group by name) as result2
on tbl4.name=result2.name
inner join
(select count(*)as count3,name from tbl3 group by name) as result3
on tbl4.name=result3.name

please try this query and let me know
select result1.cnt,result2.cnt,result2.cnt,result1.cnt +
result2.cnt - result3.cnt as total1,
result1.cnt + result2.cnt as total2
from
(select field,COUNT(*) cnt from tbl1 group by field) as result1
join
(select field,COUNT(*) cnt from tbl2 group by field) as result2
on result1.field=result2.field
join
(select field,COUNT(*) cnt from tbl3 group by field) as result3
on result3.field=result2.field
join tbl4
on tbl1.field = tbl4.field

You would have to wrap your query in a subselect to be able to access the aliased column names:
SELECT a.result1 + a.result2 - a.result3 AS total1,
a.result1 + a.result2 AS total2
FROM (
select (select count(*) from tbl1 group by field) as result1,
(select count(*) from tbl2 group by field) as result2,
(select count(*) from tbl3 group by field) as result3
) a
But this would actually be a much better solution:
SELECT a.cnt + b.cnt - c.cnt AS total1,
a.cnt + b.cnt AS total2
FROM (SELECT COUNT(*) cnt FROM tbl1 GROUP BY field) a
CROSS JOIN (SELECT COUNT(*) cnt FROM tbl2 GROUP BY field) b
CROSS JOIN (SELECT COUNT(*) cnt FROM tbl3 GROUP BY field) c

Related

add select query result from tableA as a new column in tableB

I am creating a new table from joining two tables through below query:
select a.name, a.number, b.id, b.sub_num
from tableA a left join
tableB b
on a.number = concat(id,'-',Cast(sub_num as varchar);
Here, I want to add a new column into the new table which is select query result on tableA.
The table data would be something like below:
enter image description here
I am trying to use below query which is not correct as it is giving me multiple rows. I need sum of dext_number for condition dext_id = 17501 and group by of name and number columns.
select a.name, a.number, b.id, b.sub_num,
(select sum(dext_number) from tableA where dext_id = 17501 group by name, number) as newcol
from tableA a left join tableB b
on a.number = concat(id,'-',Cast(sub_num as varchar);
What is the best way to add this column here?
use following query
select a.name, a.number, b.id, b.sub_num, (select sum(dext_number) over(partition by name, number) from tableA
where dext_id = 'xyz' limit 1) as newcol
from tableA a
left join tableB b on a.number = concat(id,'-',Cast(sub_num as varchar);
If you want the exact output of the query image, use the following query
select L.name,L.number,L.dext_id,L.dext_number,
case when L.num > 1 then newcol
else NULL
end as newcol
from
(select *,
count(dext_number) over(partition by name, number) as num,
sum(dext_number) over(partition by name, number) as newcol
from tableA) L left join tableA R on L.dext_id = R.dext_id and L.name= R.name and L.number = R.number and L.dext_number = R.dext_number
And the combination of the first query with tableB will be as follows
select a.name, a.number, b.id, b.sub_num, (select
case when L.num > 1 then newcol
else NULL
end as newcol
from
(select *,
count(dext_number) over(partition by name, number) as num,
sum(dext_number) over(partition by name, number) as newcol
from Test) L left join Test R on L.dext_id = R.dext_id and L.name= R.name and L.number = R.number and L.dext_number = R.dext_number limit 1) as newcol
from tableA a
left join tableB b on a.number = concat(id,'-',Cast(sub_num as varchar);

UNION with cross table where clause

(SELECT *, 0 AS user FROM table1)
UNION
(SELECT * FROM table2 WHERE unix >= {$threemonths})
ORDER BY unix DESC;
I need to add:
WHERE table2.identifier = table1.identifier or something
I want to get all from table1 and only rows from table2 where identifier is found in the results from table1's identifier column.
Please see if this works for you
(SELECT *, 0 AS user FROM table1)
UNION
(SELECT * FROM table2 WHERE unix >= {$threemonths} and exists (select 'Y' from table1 a where a.identifier = table2.identifier))
ORDER BY unix DESC;
Could be
SELECT *, 0 AS user FROM table1
UNION
SELECT * FROM table2 WHERE unix >= {$threemonths}
INNER JOIN table1 on table2.identifier = table1.identifier
ORDER BY unix DESC;

SQL join table to selected records

Example:
SELECT SUM(SALARY) FROM (SELECT * FROM table1 WHERE id > 10) a LEFT JOIN table2 b on a.person = b.person
I want join table2 records only to (SELECT * FROM table1 WHERE id > 10) records, my example is not correct.
table1 contain 100mln records and I cant join table2 to all records I must use subquery
I'm assuming, you salary is not summing up correctly (you are getting more than you expect). This is because LEFT JOIN will leave NULL for the rowsthat doesn't have match in b.
For this SQL:
SELECT a.*, b.*
FROM (select * from (SELECT 123 AS Salary,
'Tom' AS person
UNION
SELECT 343 AS Salary,
'Bob' AS person
UNION
SELECT 877 AS Salary,
'Tom' AS person) as t where t.Salary > 123) a
LEFT JOIN (SELECT *
FROM (SELECT 'Tom' AS person,
1 AS id
UNION
SELECT 'Bob' AS person,
2 AS id) AS t
WHERE t.id = 1) AS b
ON a.person = b.person
you will have this output:
So INNER JOIN should work for you.
SELECT SUM(SALARY) FROM (SELECT * FROM table1 WHERE id > 10) a
LEFT JOIN table2 b on a.person = b.person
Hopefully this will get you going in the correct direction....
select sum(a.salary)
from table1 a
left join table2 b on a.person = b.person and b.salary_type = "something"
where a.id > 10
;

MYSQL Performance Tuning with group by clause

I have a query like this.
SELECT count(*)
FROM table1 e
WHERE e.column1=1
AND e.id IN
(SELECT MAX(ID)
FROM table2 A
WHERE A.column1=1
AND A.date=CURDATE()
GROUP BY A.column2);
When I run this query it is taking too much of time as I am having thousands of records. How can I tune the query to perform better.
Thanks in advance.
EDIT: column2 in table2 is id of Table1
Change in (. . .) To use join instead. Like
SELECT count(*)
FROM table1 AS e
Inner join
(
SELECT MAX(ID)
FROM table2 A
WHERE A.column1 = 1
AND A.date = CURDATE()
GROUP BY A.column2
) t2 on e.id = t2.id
WHERE e.column1 = 1
Maybe:
SELECT count(*)
FROM table1 e
WHERE e.column1=1
AND EXISTS
(SELECT *
FROM table2 A
WHERE A.column1=1
AND A.date=CURDATE()
AND A.ID = e.id);

Sub-query with count(*)

How to get the data that is failed that associate with left(number,7) from sub query count(*) data?
For example I did this:
SELECT * FROM table1 WHERE outcome = 'Fail' AND left(number,7) =
(SELECT count(*) as total, left(number,7) as prefix
FROM table1 where outcome like '%Passed%'
group by prefix order by total desc limit 250)
This wont work because there are two fields in the sub-query.. so how to get around that?
You can use JOIN instead of subquery:
SELECT t1.*, t2.total, ...
FROM table1 AS t1
INNER JOIN
(
SELECT count(*) as total, left(number,7) as prefix
FROM table1
where outcome like '%Passed%' AND outcome = 'Fail'
group by prefix
order by total desc limit 250
) AS t2 ON t2.prefix = left(t1.number,7)
Try this query
SELECT *
FROM
table1 a
INNER JOIN
(SELECT
count(*) as total,
left(number,7) as prefix
FROM
table1
where
outcome like '%Passed%'
group by
prefix
order by
total desc limit 250)b
ON
a.outcome = 'Fail' AND
left(number,7) = b.prefix