MySQL-select 10 rows with limit on categories column - mysql

I have a table in my database which has 3 columns: (id, business_id, name). I need to write a query which selects 10 rows from table which have id greater than a specific value and the point is that not more than 5 rows must be selected for each business_id. how to include this criteria in the query?
so for example if we have these rows in table:
1 A JAD
2 A LPO
3 A LMN
4 A ABC
5 A QWE
6 A WER
7 B TYU
8 B POI
9 B AQZ
10 B UYT
11 C CDE
12 C XYZ
the desired result is (for id>0):
1 A JAD
2 A LPO
3 A LMN
4 A ABC
5 A QWE
7 B TYU
8 B POI
9 B AQZ
10 B UYT
11 C CDE

If you are using MySQL 8+, then ROW_NUMBER can be used here:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY business_id ORDER BY id) rn
FROM yourTable
)
SELECT id, business_id, name
FROM cte
WHERE rn <= 5;

In older versions of MySQL, you can use:
select t.*
from t
where id > #id and
id < any (select t2.id
from t t2
where t2.business_id = t.business_id
order by id asc
limit 1 offset 4
)
limit 10;
The any is to handle the case where a business has fewer than four rows.

Related

Select multiple tables with only unique users and ordered by latest id

I have 2 tables, first one is called members:
id name show
1 John 1
2 Wil 1
3 George 1
4 Chris 1
Second is called score:
id user_id score
1 1 90
2 1 70
3 2 55
4 3 30
5 3 40
6 3 100
7 4 30
user_id from score is the id of members.
What I want is to show a scorelist with unique members.id, ordered by score.score and order by the latest score.id.
I use the following code:
SELECT members.id, members.show, score.id, score.user_id, score.score FROM members
INNER JOIN score ON score.user_id = members.id
WHERE members.show = '1'
GROUP BY score.user_id
ORDER BY score.score DESC, score.id DESC
The output is not ordered by the latest score.id, but it does show only unique user_id's:
id user_id score
1 1 90
3 2 55
4 3 30
7 4 30
It should be like:
id user_id score
6 3 100
2 1 70
3 2 55
7 4 30
I hope you can help me
You could use:
with cte as (
select id,
user_id,
score,
row_number() over(partition by user_id order by id desc) as row_num
from score
) select cte.id,user_id,score
from cte
inner join members m on cte.user_id=m.id
where row_num=1
order by score desc;
Demo
If your MySQL server doesn't support windows function, use:
select s.id,s.user_id,s.score
from score s
inner join members m on s.user_id=m.id
where s.id in (select max(id) as id
from score
group by user_id
)
order by score desc;
Demo

SELECT with amount of all rows of associated table and join this rows. MySQL

I have 2 tables in MySQL:
Table A
id
1
2
3
...
100
Table B
id
boolean
table_a_id
1
0
1
2
1
1
3
1
1
...
...
...
5300
1
100
Table.A has many Table.B.
So i want to SELECT 3 rows from Table.A with additional field in which amount of all associated B rows is calculated, but SELECT from A only which have 100 or more rows in B (ORDER by total_b_rows DESC LIMIT 3) and also all associated rows in B should have at least 85% of true value in boolean column. And amount of joined B rows should be 5.
Result
id
total_b_rows
table_b.id
table_b.boolean
1
0
1
0
1
1
1
1
1
1
1
1
...
...
...
...
3
1
100
1
Total rows: 15
Help please!
You can use window functions to calculate the thresholds and then order and limit to 15 rows (that ensures there are exactly 3 table a ids):
select b.*
from (select b.*,
count(*) over (partition by table_a_id) as cnt,
avg(boolean) over (partition by table_a_id) as ratio,
row_number() over (partition by table_a_id order by table_a_id) as seqnum
from b
) b
where cnt > 100 and ratio > 0.85 and seqnum <= 5
order by table_a_id
limit 15

MySQL Check if a value is within the range of values derived from a subquery

I need help with a query, I have a table ,here is an example
Item Code Qty Price Supplier
1234 1 20 A
1234 3 15 B
1234 6 2 C
4321 2 8 D
4321 7 1 A
4321 9 5 G
5432 8 10 E
5432 3 2 F
5467 5 9 H
5467 5 7 K
I have a subquery which contains distinct Item code, max(price) and 75%of max(price),this is the result.
Item Code Max value Min Value
1234 20 15
4321 8 6
5432 10 7.5
5467 9 6.75
and I need pull only those rows from first table if the price falls within the range of second table for the particular Item Code. Can anyone help?
You might give this a try:
SELECT
a.*
FROM items a
JOIN (
SELECT
item_code,
MAX(Price) as Max_Value,
MAX(Price) * 0.75 as Min_Value
FROM items
GROUP BY item_code) b
ON a.item_code = b.item_code
WHERE a.price between b.Min_Value AND b.Max_Value
order by a.item_code, a.price ASC
I will get first the max price per itemCode and join to the main table using itemCode and chwck that the price is between 75% of max and max price per item.
Select tbl.*
From myTable tbl
Join (
Select item_code,
max(price) as mx,
Round(max(price)*.75,0) as mx75
From myTable
Group by item_code) tab
On tbl.item_code = tab.item_code
And tbl.price between tab.mx75 and tab.mx
Order by 1, 4

MySQL multiple count based on two column with multiple GROUP BY in single table

I have a query like below, it is working fine but not optimized, since it takes 1.5 sec to run. How to make this to an optimized result?
select h.keyword_id,
( select count(DISTINCT(user_id)) from history where category_id = 6
and h.keyword_id=keyword_id group by keyword_id ) as cat_6,
( select count(DISTINCT(user_id)) from history where category_id = 7
and h.keyword_id = keyword_id group by keyword_id ) as cat_7
from
history h group by h.keyword_id
History table
his_id keyword_id category_id user_id
1 1 6 12
2 1 6 12
3 1 7 12
4 1 7 12
5 2 6 13
6 2 6 13
7 2 7 13
8 3 6 13
Result:
keyword_id cat_6 cat_7
1 2 2 (unique users)
2 2 1
3 1 0
You can rewrite your query like this:
select h.keyword_id,
count(distinct if(category_id = 6, user_id, null)) as cat_6,
count(distinct if(category_id = 7, user_id, null)) as cat_7
from
history h
group by h.keyword_id
Your desired result based on the sample data is by the way false. In each keyword_id there's always just one distinct user_id.
you can see the query in action in an sqlfiddle here
For more optimization, you'd have to post the result of show create table history and the output of explain <your_query>;

How to fetch specific number of row on basis of score

Have to show on specific count . Means i have to show max score value 4 times then less than that score to 3 times and so on
I have table like:-
ID Score
1 1
2 1
3 1
4 1
5 2
6 2
7 2
8 3
9 3
10 4
11 4
12 4
and I am expecting output like:-
Score
1
1
1
2
2
3
4
Try this:
SELECT Score
FROM
(SELECT a.Score, a.ID, count(*) as RN FROM TableName a
JOIN TableName b ON a.Score = b.Score AND a.ID >= b.ID
GROUP BY a.Score, a.ID) T
WHERE RN>1
Result:
SCORE
1
1
1
2
2
3
4
4
An example in SQL Fiddle.
Explanation:
In the inner query, we are selecting a row number partitioned by ID and order by score. And then we select Score from the inner query whose Row number is greater than 1 (inorder to omit 1 record).
SELECT x.*
FROM my_table x
JOIN my_table y
ON y.marks = x.marks
AND y.id <= x.id
GROUP
BY x.marks
, x.id
HAVING COUNT(0) <= MAX(4-x.marks)
ORDER
BY marks DESC,id;