I have this query, it works but I'm not sure if it's the best approach and I don't get what I want.
I need to select the query contained in the "IN" clause first, then union with others. Entire row returned must be 40.
SELECT *
FROM (
SELECT * FROM tbl_x a WHERE id IN(11,20,30)
UNION ALL
SELECT * FROM tbl_x b WHERE exam_group='jpx' AND subject='chemistry'
) ab
GROUP BY id LIMIT 40
The next query should to return same data in simple way:
SELECT *
FROM tbl_x
WHERE
id IN (11,20,30)
OR (exam_group='jpx' AND subject='chemistry')
ORDER BY id IN (11,20,30) DESC, id
LIMIT 40;
Related
In MySql I have a complex SELECT which returns a table of about 500k rows and without primary key.
I would like to select 10 rows based on the different position they have in the resulting table, as efficiently as possible.
I tried using LIMIT:
SELECT * FROM table_name LIMIT 5,1;
efficient but select only one row.
I tried with UNION and LIMIT, but I have to do the complex SELECT several times:
(SELECT * FROM table_name LIMIT 5,1)
UNION
(SELECT * FROM table_name LIMIT 1000,1)
UNION
(SELECT * FROM table_name LIMIT 50000,1)
...
Is there a more efficient way to get what I want?
In order to get the positions you must sort the data; there is no way around that. So, number your rows by the desired order and pick the positions you want:
select *
from
(
select t.*, row_number() over (order by ...) as rn
from table_name t
) numbered
where rn in (6, 1001, 50001);
table 1 in my db has many columns including id and time. an id is sent to the server, then I have to extract its corresponding time (let's say t) from table and run a query like this:
SELECT * FROM(
(SELECT * FROM table1 WHERE time>t AND ...clause 1...) // query A
UNION
(SELECT * FROM table1 WHERE time>t AND ...clause 2...) // query B
) h LIMIT 24;
how to include a subquery in the query mentioned above which extracts t and makes it accessible by query A and query B?
I think you need Mysql WITH (Common Table Expression) here,
WITH CTE AS (
SELECT * FROM table1 WHERE time>t
)
SELECT * FROM (
(SELECT * FROM CTE AND ...clause 1...) // query A
UNION
(SELECT * FROM CTE AND ...clause 2...) // query B
) h LIMIT 24;
I have two table name 'activites' & 'archived_activities'. I devide my activities table record into another table record. Activities table contain only first 200 latest activities of users and remaining record moved to archived_activities table. Now I want to join both table only when activities table return null then I want to use same offset and limit for archived_activities table to fetch next record. Below I my query that is not working fine.
SELECT * FROM activities WHERE user_id=87 LIMIT 180,20
UNION ALL
SELECT * FROM activities WHERE user_id=87 LIMIT 180,20
But this query working not fine.
Any help?
One approach here would be to do a union to get both current and archived records into one logical table, but to order them such that current records get higher priority, should they exist. I assign a position of 1 to current records and 2 to archived records. Then, I order by this position and retain 200 records.
SELECT col1, col2, ...
FROM
(
SELECT col1, col2, ..., 1 AS position
FROM activities
WHERE user_id = 87
UNION ALL
SELECT col1, col2, ..., 2
FROM archived_activities
WHERE user_id = 87
) t
ORDER BY
position
LIMIT 200;
You can use NOT EXISTS() :
SELECT * FROM activities
WHERE user_id=87
LIMIT 180,20
UNION ALL
SELECT * FROM archieve_activities
WHERE NOT EXISTS(SELECT 1 FROM activities
WHERE user_id = 87)
AND user_id=87
LIMIT 180,20
You can try this query
select * from activities as a
union all
select * from archived_activities as b
where b.user_id not in
(select r.user_id
from activities as r)
Neither of the UNION Answers does the LIMIT 180, 20 optimally for the general case.
( SELECT ... ORDER BY .. LIMIT 200 )
UNION ALL
( SELECT ... ORDER BY .. LIMIT 200 )
ORDER BY .. LIMIT 180, 20
This will get the 'right' 20 rows regardless of whether either SELECT finds less than, or more than, 200 rows.
(Note, the '200' comes from '180+20'.)
I have a query that gets rows ordered by column a and limited to 100. Then I want to run a query on that result that gets rows ordered by column b and limited by 50.
How can I do this?
Do the first order by/limit in a derived table. Then do the second order by/limit on the derived table's result:
select * from
(
select * from tablename
order by a
limit 100
) dt
order by b
limit 50
You should use select from select statement:
select a, b
from (
select a, b
from table1
order by a
limit 100
)
order by b
limit 50
I have two queries one will return data ordered by likes and in the user city the other one return data by the distance .
so if query 1 return : id 1,2,3 (order by likes)
and query 2 return : id 4,5,6 (order by distance)
i need the final set results to be 1,2,3,4,5,6
i've tried to do union between the two queries but it's not working. any other suggestions ?
You can use left join or union according to this link.
Union ALL also works like you can see here.
Example: SELECT 1 UNION ALL SELECT 2
the solution was to put a limit to each query then the union will work correct :
(SELECT DISTINCT ID, 'a' as type,... FROM table1 GROUP BY ID ORDER BY likesDESC limit 50) union all( SELECT DISTINCT ID, 'b' as type,....FROM table1 GROUP BY ID ORDER BY distance limit 50) order by type asc.