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
Related
I wrote a SQL query to get users with the largest number of purchases.
SELECT name, count(*) as C
FROM sells
GROUP BY user_id
ORDER BY C
LIMIT 1
But, If i have two users with same number of purchase this query can not detect. what's the solution?
Try subquery:
SELECT name, count(*) as C
FROM sells
GROUP BY user_id
HAVING C >= ALL
(SELECT count(*)
FROM sells
GROUP BY user_id)
This will work in any sql version, without using LIMIT in a subquery
Write a subquery that gets the maximum count. Then use HAVING to select all the rows with that count.
SELECT name, COUNT(*) AS c
FROM sells
GROUP BY user_id
HAVING c = (SELECT COUNT(*) c
FROM sells
GROUP BY user_id
ORDER BY c DESC
LIMIT 1)
or this can be done as a join between subqueries:
SELECT t1.*
FROM (SELECT name, COUNT(*) AS c
FROM sells
GROUP BY user_id) AS t1
JOIN (SELECT COUNT(*) AS c
FROM sells
GROUP BY user_id
ORDER BY c DESC
LIMIT 1) AS t2
ON t1.c = t2.c
SELECT name, COUNT(*)
FROM sells
GROUP BY user_id
HAVING COUNT(*) = ( SELECT MAX(C) FROM ( SELECT COUNT(*) AS C FROM sells GROUP BY user_id ) )
You are using LIMIT 1 in the query. It restricts the number of records in the output to one. If you wish to see all the records from the output remove this LIMIT.
If you only need to see one row per every same count, you can modify this query as:
SELECT GROUP_CONCAT(name), count(*) as C
FROM sells
GROUP BY user_id
ORDER BY C
LIMIT 1
This will concatenate both the names having similar counts.
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
I want to join join 2 select in single query :
Here are the two queries.
SELECT player_id, SUM(score) score
FROM (
SELECT id_p1 player_id, score_p1 score
FROM matchs
UNION ALL
SELECT id_p2, score_p2
FROM matchs
) q
GROUP BY player_id
AND
SELECT player_id, SUM(score) score
FROM (
SELECT id_p1 player_id, score_p2 score
FROM matchs
UNION ALL
SELECT id_p2, score_p1
FROM matchs
) q
GROUP BY player_id
Thank you !
Try this
SELECT table1.player_id, table1.score score1, table2.score score2,
abs(table1.score - table2.score) difference
FROM (
SELECT player_id, SUM(score) score
FROM (
SELECT player1_id player_id, score_p1 score FROM matchs
UNION ALL
SELECT player2_id , score_p2 FROM matchs
) q GROUP BY player_id
) table1
INNER JOIN
(
SELECT player_id, SUM(score) score
FROM (
SELECT player1_id player_id, score_p2 score FROM matchs
UNION ALL
SELECT player2_id , score_p1 FROM matchs
) q GROUP BY player_id
) table2 ON table1.player_id = table2.player_id
SQL Fiddle Demo
Ideally, one would perform this operation using a FULL JOIN:
SELECT COALESCE(t1.player1_id, t2.player2_id)
SUM(COALESCE(t1.score_p1,0) + COALESCE(t2.score_p2,0))
FROM table_name t1
FULL JOIN table_name t2 ON t1.player1_id = t2.player2_id
GROUP BY COALESCE(t1.player1_id, t2.player2_id)
However, sadly MySQL does not have native support for such a join operation. Instead, one can simulate it by making a UNION between a LEFT JOIN and a RIGHT JOIN, then aggregating:
SELECT p, SUM(s) FROM (
SELECT t1.player1_id p, SUM(t1.score_p1 + IFNULL(t2.score_p2,0)) s
FROM table_name t1
LEFT JOIN table_name t2 ON t1.player1_id = t2.player2_id
GROUP BY t1.player1_id
UNION
SELECT t2.player2_id, SUM(IFNULL(t1.score_p1,0) + t2.score_p2)
FROM table_name t1
RIGHT JOIN table_name t2 ON t1.player1_id = t2.player2_id
GROUP BY t2.player2_id
) t GROUP BY p
See it on sqlfiddle.
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
I have a table with lots of fields in mysql
I need a query to return (in the same raw!) the top last 3 dates (dates can have large gaps between them)
ie:
2012/01/20
2012/01/18
2012/01/12
2012/01/10
2012/01/04
etc...
Any help will be appreciated
I must get them in the same row!
This is the query I am trying to use with no success:
SELECT a.id, a.thedate, b.id AS id1, b.thedate AS thedate1, c.id AS id2, c.thedate as thedate2
FROM mytable AS a INNER JOIN mytable AS b ON a.id = b.id INNER JOIN mytable AS c ON b.id=c.id
WHERE c.thedate = SELECT MAX(thedate)
EDIT :
SELECT group_concat(date) FROM (SELECT date FROM my_table ORDER BY date DESC LIMIT 3) AS temp
Corrected-
SELECT group_concat(date) FROM ( select date from table_name order by date desc limit 3) as a
SELECT GROUP_CONCAT(a.date )
FROM (
SELECT date
FROM my_table
ORDER BY date DESC
LIMIT 3
) AS a