I need to order a MySQL query by the resulting SUM of multiple subqueries.
Here's some example code for what I'm trying to do:
SELECT ...
(SELECT SUM(
(SELECT one_result ... LIMIT 1) as plays1,
(SELECT one_result ... LIMIT 1) as plays2,
(SELECT one_result ... LIMIT 1) as plays3
)) as total_plays
FROM plays
ORDER BY total_plays
Basically, I need to run three subqueries that'll each return an integer.
I need to order the entire query by the SUM() of these integers.
When I try to run this query I get a syntax error.
Could someone let me know what the proper syntax is for summing multiple subqueries?
I've also already tried:
SELECT ...
(SELECT one_result ... LIMIT 1) as plays1,
(SELECT one_result ... LIMIT 1) as plays2,
(SELECT one_result ... LIMIT 1) as plays3
SUM(plays1, plays3, plays3) as total_plays
FROM plays
ORDER BY total_plays
EDIT
#JoeC and #SATSON provided similar answers that solved this. Here's my (working) real query in case this helps anyone else get started on their own query:
````
SELECT song.title as title,
song.file_name as unique_name,
song.artist as artist,
(SELECT difficulty FROM chart WHERE id = song.easy_chart ORDER BY scoring_version ASC LIMIT 1) as easy_difficulty,
(SELECT difficulty FROM chart WHERE id = song.hard_chart ORDER BY scoring_version ASC LIMIT 1) as hard_difficulty,
(SELECT difficulty FROM chart WHERE id = song.master_chart ORDER BY scoring_version ASC LIMIT 1) as master_difficulty,
(plays.easy_plays + plays.hard_plays + plays.master_plays) as total_plays
FROM song
INNER JOIN (SELECT parent_song_id,
(SELECT global_plays ORDER BY scoring_version ASC LIMIT 1) as easy_plays,
(SELECT global_plays ORDER BY scoring_version ASC LIMIT 1) as hard_plays,
(SELECT global_plays ORDER BY scoring_version ASC LIMIT 1) as master_plays
FROM chart) as plays
ON plays.parent_song_id = song.id
ORDER BY total_plays DESC
LIMIT 9
OFFSET 0
````
Ummm, what about
SELECT *, plays1 + plays2 + plays3 as total_play from
(SELECT ...
(SELECT one_result ... LIMIT 1) as plays1,
(SELECT one_result ... LIMIT 1) as plays2,
(SELECT one_result ... LIMIT 1) as plays3
FROM plays)
ORDER BY total_plays
Try Like this
SELECT sum(plays1) as total_plays from (
(SELECT one_result as plays1 ... LIMIT 1)
union all
(SELECT one_result as plays1 ... LIMIT 1 )
union all
(SELECT one_result as plays1 ... LIMIT 1)
)
as plays
ORDER BY total_plays
Related
Can I somehow combine these two queries into one in MySQL 5.7 without global variables and stored procedures?
define p1_id, p2_id int;
...
insert into Cards_in_game_decks select * from Cards_in_decks where Cards_in_decks.player_id=p1_id order by rand() limit 10;
insert into Cards_in_game_decks select * from Cards_in_decks where Cards_in_decks.player_id=p2_id order by rand() limit 10;
You just need to do a union:
insert into Cards_in_game_decks select * from (
(select * from Cards_in_decks where Cards_in_decks.player_id=p1_id order by rand() limit 10)
union all
(select * from Cards_in_decks where Cards_in_decks.player_id=p2_id order by rand() limit 10)
) random_cards
fiddle
To get up to 10 cards per player for up to 6 players listed in a Players table, you just have to get repetitive:
insert into Cards_in_game_decks select * from (
(select * from Cards_in_decks where Cards_in_decks.player_id=(select id from Players where game_id=1 order by id limit 0,1) order by rand() limit 10)
union all
(select * from Cards_in_decks where Cards_in_decks.player_id=(select id from Players where game_id=1 order by id limit 1,1) order by rand() limit 10)
union all
(select * from Cards_in_decks where Cards_in_decks.player_id=(select id from Players where game_id=1 order by id limit 2,1) order by rand() limit 10)
union all
(select * from Cards_in_decks where Cards_in_decks.player_id=(select id from Players where game_id=1 order by id limit 3,1) order by rand() limit 10)
union all
(select * from Cards_in_decks where Cards_in_decks.player_id=(select id from Players where game_id=1 order by id limit 4,1) order by rand() limit 10)
union all
(select * from Cards_in_decks where Cards_in_decks.player_id=(select id from Players where game_id=1 order by id limit 5,1) order by rand() limit 10)
) random_cards
fiddle
There are likely much better ways to do this in mysql 8.
Need assistance with simplifying this SQL query to possibly a single SELECT:
(SELECT * FROM `deals`
WHERE category_id = 1
ORDER BY id desc
LIMIT 10)
UNION
(SELECT * FROM `deals`
WHERE category_id = 2
ORDER BY id desc
LIMIT 10)
UNION
(SELECT * FROM `deals`
WHERE category_id = 4
ORDER BY id desc
LIMIT 10)
UNION
(SELECT * FROM `deals`
WHERE category_id = 5
ORDER BY id desc
LIMIT 10)
UNION
(SELECT * FROM `deals`
WHERE category_id = 6
ORDER BY id desc
LIMIT 10)
UNION
(SELECT * FROM `deals`
WHERE category_id = 8
ORDER BY id desc
LIMIT 10)
UNION
(SELECT * FROM `deals`
WHERE category_id = 9
ORDER BY id desc
LIMIT 10)
UNION
(SELECT * FROM `deals`
WHERE category_id = 10
ORDER BY id desc
LIMIT 10)
UNION
(SELECT * FROM `deals`
WHERE category_id = 17
ORDER BY id desc
LIMIT 10)
I've been told to try using GROUP BY and HAVING. However, any query I tried didn't work in the slightest...
Any help will be greatly appreciated!
EDIT - apologies, forgot to mention database engine is MySQL
You can condense this down with a window function to limit each group bucket to 10.
SELECT
*
FROM
(
SELECT
*,
ROW_NUMBER() OVER PARTITION BY(category_id ORDER BY id DESC) AS GroupOrder
FROM `deals`
WHERE category_id BETWEEN 1 AND 10
)AS X
WHERE
GroupOrder<=10
I'm not sure, I need to know if you need that limit of 10, is this like take top 10 of all those things?
if not then
SELECT * FROM `deals`
WHERE category_id between 0 and 10 or category_id=17
ORDER BY category_id asc, id desc
For older versions of MySQL without the windowing functions, here is the code.
SELECT T1.ID, T1.Category_ID, T1.Name
FROM (
SELECT #row_num := IF(#prev_value=concat_ws('',t.Category_ID),#row_num+1,1) AS RowNumber
,t.*
,#prev_value := concat_ws('',t.Category_ID)
FROM data t,
(SELECT #row_num := 1) x,
(SELECT #prev_value := '') y
ORDER BY t.Category_ID
) T1
WHERE T1.RowNumber < 10
AND T1.Category_ID IN (1,2,3,4,5,6,7,8,9,10)
You will need to add the necessary field names to the other select.
This uses the technique described here
I am making multiple unions on the same tables
however i need to order the records of the second table by rand()
keeping in mind that I DO NOT want to have duplicate records since Iam using order by rand()
Example:
news table has the following data: (test1,test2,test3)
ads table has the following data: (ads1,ads2,ads3)
The result should be like this:
news are sorted by id
ads are sorted by rand() : which means ads2 may comes in the top of the list, and maybe ads1 comes in the top of the list and so on..
This is my sql statement:
(select news.title
from news
order by news.id desc limit 6) union
(select
advertisements.title
from advertisements
order rand() limit 1,1)
union
(select
news.title,
from news
order by news.id desc limit 6,6)
union
(select
advertisements.title
from advertisements
order by rand() limit 2,1)
Near as I can tell, you seem to want 6 news articles followed by an advertising one, and then repeated again. This is not what your query does, but I'm guessing that is the intention in using union.
I would suggest enumerating the values and then doing the sort outside:
select title
from ((select n.title, #rn := #rn + 1, 'n' as which, id
from news n cross join (select #rn := 0) params
order by n.id desc
limit 12
)
union all
(select a.title, (#rna := #rna + 1) as rn, 'a', NULL
from advertisements a cross join (select #rna := 0) params
order rand()
limit 2
)
) na
order by (case when which = 'n' and rn <= 6 then 1
when which = 'a' and rn = 1 then 2
when which = 'n' and rn <= 12 then 3
when which = 'a' and rn = 1 then 4
end),
id desc;
I would like to get values without the smallest and the biggest ones, so without entry with 2 and 29 in column NumberOfRepeating.
My query is:
SELECT Note, COUNT(*) as 'NumberOfRepeating'
WHERE COUNT(*) <> MAX(COUNT(*))AND COUNT(*) <> MIN(COUNT(*))
FROM Note GROUP BY Note;
SELECT Note, COUNT(*) as 'NumberOfRepeating'
FROM Notes
GROUP BY Note
HAVING count(*) <
(
SELECT max(t.maxi)
FROM (select
Note, COUNT(Note) maxi FROM Notes
GROUP BY Note
) as t
)
AND
count(*) >
(
SELECT min(t.min)
FROM (select
Note, COUNT(Note) min FROM Notes
GROUP BY Note
) as t
)
try this code.
One method would use order by and limit, twice:
select t.*
from (select t.*
from t
order by NumberOfRepeating asc
limit 99999999 offset 1
) t
order by NumberOfRepeating desc
limit 99999999 offset 1;
Try this code,
Select * from Note where NumberOfRepeating < (select MAX(NumberOfRepeating) from Note ) AND NumberOfRepeating > (select MIN(NumberOfRepeating) from Note );
Here in the code, as in your table Note is the name of the table, and NumberOfRepeating is the column name, as in your table.
Try this. It should work
SELECT *
FROM ( SELECT Note, COUNT(*) as 'NumberOfRepeating'
FROM Notes
GROUP BY Note
ORDER BY NumberOfRepeating DESC
LIMIT 1, 2147483647
) T1
ORDER BY T1.NumberOfRepeating
LIMIT 1, 2147483647
I got the error #1349 - View's SELECT contains a subquery in the FROM clause
mycode is:
CREATE VIEW `MyViewName` AS
SELECT *
FROM
(SELECT *
FROM (
(SELECT *
FROM `crm_clients`
WHERE ctype=1
ORDER BY rand() LIMIT 0,
3)
UNION
(SELECT *
FROM `crm_clients`
WHERE ctype=1
ORDER BY rand() LIMIT 0,
3)
UNION
(SELECT *
FROM `crm_clients`
WHERE ctype=1
ORDER BY rand() LIMIT 0,
3)
UNION
(SELECT *
FROM `crm_clients`
WHERE ctype=1
ORDER BY rand() LIMIT 0,
3)) t
ORDER BY rand())
what is the problem with this code?I am not familier with view
MySQL does not allow subqueries in the from clause when you define views.
You can do what you want as:
Create View `MyViewName` as
(SELECT * FROM `crm_clients` WHERE ctype=1 order by rand() limit 0,3)
union
(SELECT * FROM `crm_clients` WHERE ctype=1 order by rand() limit 0,3)
union
(SELECT * FROM `crm_clients` WHERE ctype=1 order by rand() limit 0,3)
union
(SELECT * FROM `crm_clients` WHERE ctype=1 order by rand() limit 0,3)
order by rand();
My guess is that you actually want to change the ctype values as well. Otherwise the query is rather strange.
Here are the restrictions on views.