Mysql UNION as a subquery with an alias field - mysql

I have a UNION query as bellow (I have simplified my working query so it is easier to read) :
SELECT count(*) FROM
(SELECT DISTINCT `tableA`.`Store Name` FROM `tableA` UNION SELECT DISTINCT `tableB`.`Store Name` FROM `tableB`) t
This works fine and results in a single number with column name COUNT(*)
I want to get this value as another column in another query so I do :
SELECT DISTINCT `tableC`.`id as PID,
(SELECT count(*) from (SELECT DISTINCT `tableA`.`Store Name` FROM `tableA` UNION SELECT DISTINCT `tableB`.`Store Name` FROM `tableB`) t) AS noofstores
WHERE
.....;
But it wont work! What am I doing wrong? This is part of a bigger query, and all the other subqueries work fine when I do
,
(SELECT .... ) AS column_name
,
Sorry for poor error description. Update :
This is my full query :
SELECT DISTINCT
`tableC`.`id` as PID,
(SELECT count(*)
from
(SELECT DISTINCT `tableA`.`Store Name` FROM `tableA` WHERE `tableA`.`id` = PID
union
SELECT DISTINCT `tableB`.`Store Name` FROM `tableB` WHERE `tableB`.`id` = PID) t) AS mycolumn_name
FROM
`tableC`
Looks like I had the union right and all, but the problem is the PID I am reffering to in the union :
1054 - Unknown column 'PID' in 'where clause'
So how do I solve this?

The PID column does not exist in the inner subquery, only in the outer query. Either you do an inner join in both of the queries in the union on tableC and do the filtering there, or you need to return the id column in the union queries and join the PID on them to do the filtering.
select tableC.id as PID, count(distinct storename)
from
(select distinct id, storename from tableA
union
select distinct id, storename from tableB) t1
inner join tableC on t1.id=tableC.id
group by tableC.id

You have to join thos two tables to get the result
SELECT DISTINCT c.id as PID from table C inner join
(SELECT count(*) from
(SELECT DISTINCT `tableA`.`Store Name` as st
FROM `tableA` UNION SELECT DISTINCT `tableB`.`Store Name` as st
FROM `tableB`) t on t.some_id=c.id WHERE

Related

Wrong count result in mysql when joining two tables

I am trying to join two tables and get the count and grouped by specific field. However, it outputs same count values even if the other table consist only two rows. How should I fix this?
Here's my code:
SELECT tbl1.preferredDay, COUNT(tbl1.preferredDay) as count_1, COUNT(tbl2.preferredDay) as count_2
FROM tblschedule as tbl1
LEFT JOIN tblappointments as tbl2 ON (tbl1.preferredDay = tbl2.preferredDay)
WHERE tbl1.preferredDay = tbl2.preferredDay
GROUP BY preferredDay;
Here is the output but it should be [15, 0][3, 3]
Your query is based on left join it will return the same count().
This is a working query for Mysql 8:
with tbl1 as (
SELECT preferredDay, count(1) as count_1
FROM tblschedule
GROUP BY preferredDay
),
tbl2 as (
SELECT preferredDay, count(1) as count_2
FROM tblappointments
GROUP BY preferredDay
)
select t1.preferredDay, t1.count_1, t2.count_2
from tbl1 t1
inner join tbl2 t2 on t1.preferredDay = t2.preferredDay
There are two WITHs to get separately the count and then an INNER JOIN to join those results
For Mysql 5.7 and lower :
select t1.preferredDay, t1.count_1, t2.count_2
from (
SELECT preferredDay, count(1) as count_1
FROM tblschedule
GROUP BY preferredDay
) as t1
inner join (
SELECT preferredDay, count(1) as count_2
FROM tblappointments
GROUP BY preferredDay
) as t2 on t1.preferredDay = t2.preferredDay

Referring to CTE in WHERE condition of UPDATE

I'm trying to run a query like this:
WITH cte AS
(
SELECT id, category, SUM(amount) AS sum_amount FROM t1 GROUP BY id, category
)
UPDATE table SET amount = cte.sum_amount WHERE id = cte.id;
However, I keep getting the error
Unknown column 'cte.id in WHERE clause'
Does anyone know how I can refer to my common table expression in the UPDATE query, or otherwise, rewrite it?
You can try below
WITH cte AS
(
SELECT id, SUM(amount) AS sum_amount FROM t1 GROUP BY category
)
UPDATE T
SET T.sum_amount= CT.sum_amount
FROM table T
JOIN cte CT
ON T.id = CT.id
Alternate way with Temporary table, you can read about CTE and Temporary Table
Temporary table:
SELECT id, category, SUM(amount) AS sum_amount
INTO #temp
FROM t1 GROUP BY id, category
Update query with temp table:
UPDATE OT
SET OT.sum_amount= TT.sum_amount
FROM table OT
JOIN #temp TT
ON OT.id = TT.id
CTE:
WITH cte AS
(
SELECT id, category, SUM(amount) AS sum_amount FROM t1 GROUP BY id,category
)
UPDATE T
SET T.sum_amount= CT.sum_amount
FROM table T
JOIN cte CT
ON T.id = CT.id

Merging multiple similar query

I can get the result from multiple but simple queries but I would like to merge them further as sub queries.
All sub queries are going to be similar to this one-
SELECT COUNT(count) AS acc1 FROM (SELECT COUNT(table.colname) AS count
FROM tablename GROUP BY tablename.sumcol HAVING count=1) as access1
likewise others will be
SELECT COUNT(count) AS acc2 FROM (SELECT COUNT(table.colname) AS count
FROM tablename GROUP BY tablename.sumcol HAVING count=2) as access2
You could use UNION ALL for get both the results in the same result set
SELECT 'acc1' , COUNT(count)
FROM ( SELECT COUNT(table.colname) AS count
FROM tablename G
ROUP BY tablename.sumcol
HAVING count=1) access1
UNION ALL
SELECT 'acc2', COUNT(count)
FROM (SELECT COUNT(table.colname) AS count
FROM tablename
GROUP BY tablename.sumcol
HAVING count=2) access2
I have addedd 'acc1' and 'acc2' literal value for a better result reading but you can avoid it
do the fact you have only a rows for both the query , if you need the two result on the same row, you can use a cross join (cartesian product)
SELECT COUNT(count) as count_acc1, T.count2
FROM ( SELECT COUNT(table.colname) AS count1
FROM tablename G
GROUP BY tablename.sumcol
HAVING count=1) access1
CROSS JOIN (
SELECT COUNT(count) as count2
FROM (SELECT COUNT(table.colname) AS count
FROM tablename
GROUP BY tablename.sumcol
HAVING count=2) access2 ) T

MySQL JOIN the result of UNION

Is it possible to join the result of UNION of two tables with the 3rd table? Something like this:
(SELECT DISTINCT `Fund_ID`, `Fund_Name` FROM `admin`
UNION
SELECT `Fund_ID`,`Fund_Name` FROM `admin_custom` WHERE `admin_custom`.`user_id` = 361) a
LEFT JOIN `qt1`
ON `qt1`.`Fund ID` = a.`Fund_ID`
but this code doesn't work. I could move JOIN inside of each SELECT query before UNION, but would rather try to JOIN with the UNION result.
How can I fix this?
Yes, it is possible. However, your code is incorrect since you're missing SELECT statement itself, because your first select becomes a rowset (runtime-created table). I.e. you have to specify SELECT operator and fields that you want to get. Simplest case:
SELECT
a.*
FROM
(SELECT DISTINCT `Fund_ID`, `Fund_Name` FROM `admin`
UNION
SELECT `Fund_ID`,`Fund_Name` FROM `admin_custom` WHERE `admin_custom`.`user_id` = 361) AS a
LEFT JOIN `qt1`
ON `qt1`.`Fund ID` = a.`Fund_ID`
SELECT * FROM
(SELECT DISTINCT `Fund_ID`, `Fund_Name` FROM `admin`
UNION
SELECT `Fund_ID`,`Fund_Name` FROM `admin_custom` WHERE `admin_custom`.`user_id` = 361) a
LEFT JOIN `qt1`
ON `qt1`.`Fund ID` = a.`Fund_ID`;

Is it optimal to use "OR" for multiple sub-queries?

I have a slow query of the following form.
SELECT DISTINCT * FROM table e
WHERE e.eid in (select eid from view1)
OR e.eid in (select eid from view1)
OR e.eid in (select eid from view2)
OR e.eid in (select eid from view3)
OR e.eid in (select eid from view4)
OR e.eid in (select eid from view5)
I am new to MySQL but is there a faster way to make this query?
May be using UNION like this:
SELECT DISTINCT * FROM table e
WHERE e.eid IN
(
SELECT eid FROM view1
UNION
SELECT eid FROM view2
UNION
SELECT eid FROM view3
UNION
SELECT eid FROM view4
UNION
SELECT eid FROM view5
)
you can use Union in your query .
SELECT DISTINCT e.*
FROM table e
INNER JOIN
(
SELECT eid FROM view1
UNION ALL
SELECT eid FROM view2
UNION ALL
SELECT eid FROM view3
UNION ALL
SELECT eid FROM view4
UNION ALL
SELECT eid FROM view5
) AS B ON e.eid = B.eid
you should use join query instead of using IN query . IN query will run for each rows of the table so it will take more time . Join query will run only one time .
Using id IN (unioned subquery) generally won't perform well.
Try using a standard join on a unioned subquery:
SELECT a.*
FROM (
SELECT eid FROM view1
UNION
SELECT eid FROM view2
UNION
SELECT eid FROM view3
UNION
SELECT eid FROM view4
UNION
SELECT eid FROM view5
) e
JOIN table a ON a.id = e.eid
The important thing here is that the ids from the views come first in the FROM table list, so that table can be accessed efficiently, not the other way around when the in indexed view result would have to be table-scanned for every row of table.
Also note there is no need for DISTINCT because the UNION inside the subquery eliminated duplicates.
This query should perform very well.