How to get the MAX value in MySQL? - mysql

How to get the MAX value in every albumID(45, 12, 22, 8) in the following table?
I tried with this query.
But it returned me the first value, not max value.(3, 6, 5, 6)
SELECT
*
FROM
(
SELECT
*
FROM
contentnew
WHERE
genreID = 1
ORDER BY
albumID DESC,
reg_count DESC
) AS newTB
GROUP BY
albumID;
Look this
If I use the

Once you group by, you can apply aggregate functions such as max on each group. In your example try:
SELECT albumID, max(reg_count) as max_count
FROM contentnew
GROUP BY albumID
This will project each albumID with the max_count in the group. In the select statement you can only use aggregate functions. The reason why we are able to project (or print) albumID is because this is the column we grouped by.
Following comments:
SELECT *
FROM contentnew as c1
WHERE c1.reg_count < (
SELECT max(c2.reg_count)
FROM contentnew as c2
WHERE c1.albumID = c2.albumID
GROUP BY c2.albumID)

You can try
select max(reg_count) from contentnew group by albumID

You are almost there, one thing that might be helpful is to use row_number() function, if you want every column from the table.
with contentnew_test
as
(
select row_number() over (partition by albumId order by reg_count desc) row
,* from
contentnew
)
select * from contentnew_test where row = 1 order by reg_count desc;
I used this as a reference as not sure about the syntax
https://www.mysqltutorial.org/mysql-window-functions/mysql-row_number-function/
Subquery will give you a result set something like this:
row albumId reg_count ...
1 1 8 ...
2 1 7 ...
3 1 3 ...
4 1 1 ...
1 2 22 ...
2 2 9 ...
3 2 6 ...
4 2 1...and so on.

Related

How can I select the second-to-last rows in a mysql table, grouped by column?

Structure is:
CREATE TABLE current
(
id BIGINT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
symbol VARCHAR(5),
UNIQUE (id), INDEX (symbol)
) ENGINE MyISAM;
id
symbol
1
A
2
B
3
C
4
C
5
B
6
A
7
C
8
C
9
A
10
B
I am using the following
SELECT *
FROM current
WHERE id
IN
(
SELECT MAX(id)
FROM current
GROUP BY symbol
)
to return the last records in a table.
id
symbol
8
C
9
A
10
B
How can I return the next-to-last results in a similar fashion?
I know that I need
ORDER BY id DESC LIMIT 1,1
somewhere, but my foo is weak.
I would want to return
id
symbol
5
B
6
A
7
C
For versions of MySql prior to 8.0, use a subquery in the WHERE clause to filter out the max id of each symbol and then aggregate:
SELECT MAX(id) id, symbol
FROM current
WHERE id NOT IN (SELECT MAX(id) FROM current GROUP BY symbol)
GROUP BY symbol
ORDER BY id;
See the demo.
SELECT *
FROM current
WHERE id IN (
SELECT DISTINCT T.id FROM current AS T
WHERE id=(
SELECT id FROM current
WHERE symbol=T.symbol
ORDER BY id DESC LIMIT 1,1
)
)
Easy if your MySql can use ROW_NUMBER. (MySql 8)
Just make it sort descending, then take the 2nd.
WITH CTE AS (
SELECT *
, ROW_NUMBER() OVER (PARTITION BY symbol ORDER BY id DESC) AS symbol_rn
FROM current
)
SELECT id, symbol
FROM CTE
WHERE symbol_rn = 2
ORDER BY id;
In MySql 7.5 you can simply self-join on the symbol, and group by.
Then the 2nd last will have 1 higher id.
SELECT c1.id, c1.symbol
FROM current c1
LEFT JOIN current c2
ON c2.symbol = c1.symbol
AND c2.id >= c1.id
GROUP BY c1.id, c1.symbol
HAVING COUNT(c2.id) = 2
ORDER BY c1.id;
id
symbol
5
B
6
A
7
C
db<>fiddle here
The performance will really benefit from an index on symbol.
You can try this;
SELECT *
FROM current
WHERE id
IN (SELECT MAX(id)
FROM current
GROUP BY symbol)
ORDER BY id DESC LIMIT 1,3
limit 1,3 says; get the last 3 results excluding the last result. You can change the numbers.

Add Additional Index to Select Query & Fetch result using greater than Index ID

I have a table in which right now I am fetching result by adding a additional index but I want to fetch result using greater than operator to Additional index id
This query gives me this
SET #a:=0;
SELECT #a:=#a+1 additional_id, output.*
FROM (SELECT sum(item_sale + item_viewed) as totalSum ,item_id FROM items WHERE item_active='1' GROUP BY item_id order by totalSum desc ) output
additional_id
item_id
totalSum
1
3
17
2
1
5
3
2
2
But i want to use greater than operator and want result like this if additional_id > 1 then find only 2 result
additional_id
item_id
totalSum
2
1
5
3
2
2
How could i achieve this ?
SELECT *
FROM (
-- your query
SELECT #a:=#a+1 additional_id, output.*
FROM (SELECT sum(item_sale + item_viewed) as totalSum ,item_id FROM items WHERE item_active='1' GROUP BY item_id order by totalSum desc ) output
-- end of your query
CROSS JOIN (SELECT #a:=0) init_variable
) AS subquery
WHERE additional_id > 1

SQL select maximum number of duplicates value in a column

Here I have this table:
Copies
nInv | Subject | LoanDate | BookCode |MemberCode|
1 |Storia |15/04/2019 00:00:00 |7844455544| 1 |
2 |Geografia |12/09/2020 00:00:00 |8004554785| 4 |
4 |Francese |17/05/2006 00:00:00 |8004894886| 3 |
5 |Matematica |17/06/2014 00:00:00 |8004575185| 3 |
I'm trying to find the value of the highest number of duplicates in the MemberCode column. So in this case I should get 3 as result, as its value appears two times in the table. Also, MemberCode is PK in another table, so ideally I should select all rows of the second table that match the MemberCode in both tables. For the second part I guess I should write something like SELECT * FROM Table2, Copies WHERE Copies.MemberCode = Table2.MemberCode but I'm missing out almost everything on the first part. Can you guys help me?
Use group by and limit:
select membercode, count(*) as num
from t
group by membercode
order by count(*) desc
limit 1;
SELECT MAX(counted) FROM
(SELECT COUNT(MemberCode) AS counted
FROM table_name GROUP BY MemberCode)
Using analytic functions, we can assign a rank to each member code based on its count. Then, we can figure out what its count is.
WITH cte AS (
SELECT t2.MemberCode, COUNT(*) AS cnt,
RANK() OVER (ORDER BY COUNT(*) DESC, t2.MemberCode) rnk
FROM Table2 t2
INNER JOIN Copies c ON c.MemberCode = t2.MemberCode
GROUP BY t2.MemberCode
)
SELECT cnt
FROM cte
WHERE rnk = 1;
Something like this
with top_dupe_member_cte as (
select top(1) MemberCode, Count(*)
from MemberTable
group by MemberCode
order by 2 desc)
select /* columns from your other table */
from OtherTable ot
join top_dupe_member_cte dmc on ot.MemberCode=dmc.MemberCode;

MySql Sum and Count for simple table

Could you help me with simple table SUM and COUNT calculating?
I've simple table 'test'
id name value
1 a 4
2 a 5
3 b 3
4 b 7
5 b 1
I need calculate SUM and Count for "a" and "b". I try this sql request:
SELECT name, SUM( value ) AS val, COUNT( * ) AS count FROM `test`
result:
name val count
a 20 5
But should be
name val count
a 9 2
b 11 3
Could you help me with correct sql request?
Add GROUP BY. That will cause the query to return a count and sum per group you defined (in this case, per name).
Without GROUP BY you just get the totals and any of the names (in your case 'a', but if could just as well have been 'b').
SELECT name, SUM( value ) AS val, COUNT( * ) AS count
FROM `test`
GROUP BY name
You need group by
select
name,
sum(value) as value,
count(*) as `count`
from test group by name ;

Get lowest shared value in a one to many relationship table

I have a one to many relationship table.
I want to get the lowest other_id that is shared between multiple id's.
id other_id
5 5
5 6
5 7
6 6
6 7
7 7
I can do this by building an SQL statement dynamically with parts added for each additional id I want to query on. For example:
select * from (
select other_id from SomeTable where id = 5
) as a
inner join (
select other_id from SomeTable where id = 6
) as b
inner join (
select other_id from SomeTable where id = 7
) as c
on a.other_id = b.other_id
and a.other_id = c.other_id
Is there a better way to do this? More specifically, is there a way to do this that doesn't require a variable number of joins? I feel like this problem probably already has a name and better solutions.
My query gives me the number 7, which is what I want.
i dont have a mysql server to test it out at the moment, but try a "group by" statement:
select
other_id
from
SomeTable
group by
other_id having count(*) > 1
order by
other_id asc
limit 1
the lowest other_id shared between all ids
select other_id
from SomeTable
group by other_id
having count(distinct id) = 3
order by other_id limit 1
or dynamically
select other_id
from SomeTable
group by other_id
having count(distinct id) = (select count(distinct id) from SomeTable)
order by other_id limit 1
or if you want to look for the lowest other_id shared between specific ids
select other_id
from SomeTable
where id in (5,6,7)
group by other_id
having count(distinct id) = 3
order by other_id limit 1
Use MIN for simple query
SELECT MIN(other_id) FROM table
Though, there seems to be working solutions I want to add my version, just to show, how smart I am ;-)
SELECT other_id FROM SomeTable a INNER JOIN SomeTable b on a.other_id=b.other_id ORDER by other_id ASC LIMIT 1