pass limit to "in" query in mysql - mysql

My table is like:
now here I want to pass limit for particular voices_id.
I mean if I want just 3 records of particular voices_id then how to do so? (3 records for voices_id=153 & 154) where to pass limit ?

This is what you can do
select *
from table_name t1
where t1.voices_id in (153,154)
and
(
select count(*) from table_name t2
where t1.voices_id = t2.voices_id and t1.id <= t2.id
) <= 3
order by t1.voices_id
;
Here the condition t1.id <= t2.id will give you last 3 entry per group, you can reverse it for first 3 entry.

It is as simple as this:
SELECT * FROM voices_talks WHERE voices_id=153 LIMIT 3
UNION ALL
SELECT * FROM voices_talks WHERE voices_id=154 LIMIT 3

Related

Condensing MySQL ordered group values

This question is an extension of mysql compress order_by values.
My table has groups of ordered numbers, with undesired gaps. How can I renumber each of these groups, while keeping the original order?
Group Order Desired Order
A 1 1
A 3 2
A 6 3
A 7 4
B 2 1
B 3 2
B 8 3
C 1 1
C 7 2
C 8 3
You can also get the desired order by using a correlated sub query without using and variables
select t1.*,
(
select count(*)
from demo t2
where t1.`group` = t2.`group`
and t1.`order` > t2.`order`
) + 1 desiredorder
from demo t1
DEMO
Or to update same table with your desired order you can use below query
update demo a
join (select t1.*,(
select count(*)
from demo t2
where t1.`group` = t2.`group`
and t1.`order` > t2.`order`
) + 1 desiredorder
from demo t1
) b on a.`group` = b.`group`
and a.`order` = b.`order`
set a.`order` = b.desiredorder
DEMO
Note make sure to add an index on group and order column for better performance.
You can create a variable to store the previous value of group and another one for the desiredorder. Essentially this is a mimic of a Window Function ROW_NUMBER which MySql doesn't support.
I renamed the columns as group=col1, order=col2
select col1,
col2,
neworder
from (
select t.col1,
t.col2,
case when #prev=t.col1 then #id:=#id+1 else #id:=1 end as neworder,
#prev:=t.col1
from (select #prev:=null, #id:=0) a,
toorder t
order by t.col1
) a
See it working here: http://sqlfiddle.com/#!9/9d8528/2
The external query is only needed if you want to pull out only those three columns.

How to combine two fields value in mysql

This is output
but i want
in this table tb_user_connection i get 4 row but i want only 3 so, if i get connection in 1 and 2 so not get repeated column.
i try below query and this is codeigniter project.
my query:
SELECT * FROM `tb_user_connection` WHERE `connection_type` = 'a' AND (user_id = '1' OR connection_id='1')
You can do this:
select *
from your_table
where user_id <= connection_id
union all
select *
from your_table t
where user_id > connection_id
and not exists (
select 1
from your_table t1
where t1.user_id = t.connection_id
and t1.connection_id = t.user_id
) t1;

Select rows around a specified row, combined with WHERE and ORDER BY

I have a table with 3 fields: id, public, date.
How can I make a MySQL query so that the rows are ordered by date, rows having public = false are omitted, and only the 5 rows before and the 5 rows after the row with id = x are fetched? (The row with id = x can of course also be fetched.)
Assuming "before" and "after" refer to the date, then you can use union all:
(select t.*
from table t
where t.public = false and
t.date <= (select t2.date from table t2 where t2.id = x)
order by date desc
limit 6
)
union all
(select t.*
from table t
where t.public = false and
t.date > (select t2.date from table t2 where t2.id = x)
order by date asc
limit 5
)
The first subquery gets 6 rows whose date is one or before the "x" date. The second gets 5 rows strictly afterwards.

Select max amount rows

I have a table with the following columns:
Categorie
Rubriek
Adv_nr
For each rubriek it is possible that there are 100 or more adv_nr's.
I want to select max 5 rows from each rubriek, is this possible in one query?
select * from table as t1
where (select count(*) from table as t2
where t1.rubriek = t2.rubriek and t2.adv_nr > t1.adv_nr) < 5
order by rubriek,adv_nr desc
select * from *ad_table*
where category_id IN (
select *category_table*.id
from *category_table*, *group_table*
where *category_table*.id = *group_table*.category_id)
LIMIT 5;

Select the 3 most recent records where the values of one column are distinct

I have the following table:
id time text otheridentifier
-------------------------------------------
1 6 apple 4
2 7 orange 4
3 8 banana 3
4 9 pear 3
5 10 grape 2
What I want to do is select the 3 most recent records (by time desc), whose otheridentifiers are distinct. So in this case, the result would be id's: 5, 4, and 2.
id = 3 would be skipped because there's a more recent record with the same otheridentifier field.
Here's what I tried to do:
SELECT * FROM `table` GROUP BY (`otheridentifier`) ORDER BY `time` DESC LIMIT 3
However, I end up getting rows of id = 5, 3, and 1 instead of 5, 4, 2 as expected.
Can someone tell me why this query wouldn't return what I expected? I tried changing the ORDER BY to ASC but this simply rearranges the returned rows to 1, 3, 5.
It doesn't return what you expect because grouping happens before ordering, as reflected by the position of the clauses in the SQL statement. You're unfortunately going to have to get fancier to get the rows you want. Try this:
SELECT *
FROM `table`
WHERE `id` = (
SELECT `id`
FROM `table` as `alt`
WHERE `alt`.`otheridentifier` = `table`.`otheridentifier`
ORDER BY `time` DESC
LIMIT 1
)
ORDER BY `time` DESC
LIMIT 3
You could join the table on itself to filter the last entry per otheridentifier, and then take the top 3 rows of that:
SELECT last.*
FROM `table` last
LEFT JOIN `table` prev
ON prev.`otheridentifier` = last.`otheridentifier`
AND prev.`time` < last.`time`
WHERE prev.`id` is null
ORDER BY last.`time` DESC
LIMIT 3
I had a similar requirement, but I had more advanced selection criteria. Using some of the other answers I couldn't get exactly what I needed, but I found you can still do a GROUP BY after and ORDER BY like this:
SELECT t.* FROM (SELECT * FROM table ORDER BY time DESC) t
GROUP BY t.otheridentifier
SELECT * FROM table t1
WHERE t1.time =
(SELECT MAX(time) FROM table t2
WHERE t2.otheridentifier = t1.otheridentifier)
Andomar's answer is probably best in that it doesn't use a subquery.
An alternative approach:
select *
from `table` t1
where t1.`time` in (
select max(s2.`time`)
from `table` t2
group by t2.otheridentifier
)
You can use this query to get correct answer:
SELECT * FROM
(SELECT * FROM `table` order by time DESC)
t group by otheridentifier
what about
SELECT *, max(time) FROM `table` group by otheridentifier
This also:
SELECT * FROM
OrigTable T INNER JOIN
(
SELECT otheridentifier,max(time) AS duration
FROM T
GROUP BY otheridentifier) S
ON S.duration = T.time AND S.otheridentifier = T.otheridentifier.