How to group multiple aggregate results in SQL - mysql

I have a query that returns an ID, item of highest value and maximum level that a user is on.
My query is as follows :
SELECT id,
MAX(item) AS highest_item,
MAX(level) AS highest_level
FROM data
GROUP BY 1
ORDER BY 1;
How can I query the database so that I receive a total count of unique users, who are on the same highest level and have the same highest value item?

You could get the count(distcint id) grouped by the values you need. Eg. for both the values:
select count(distinct id ), highest_item, highest_level
from (
SELECT id,
MAX(item) AS highest_item,
MAX(level) AS highest_item
FROM data
GROUP BY 1
) t
group by highest_item, highest_level
order by count(distinct id ) desc
or for highest_item
select count(distinct id ), highest_item
from (
SELECT id
MAX(item) AS highest_item,
MAX(level) AS highest_level
FROM data
GROUP BY 1
) t
group by highest_item
order by count(distinct id ) desc
of for highest_level
select count(distinct id ), highest_level
from (
SELECT id,
MAX(item) AS highest_item,
MAX(level) AS highest_level
FROM data
GROUP BY 1
) t
group by highest_level
order by count(distinct id ) desc

You can try this also
Select id,count(Id) from data group by level,item having level=max(level) and item=max(item)

Related

MySQL-ordering partitions randomly

table1 has 3 columns in my database: id, category, timestamp. I need to query the newest 3 rows from each category:
WITH ranked_rows AS
(SELECT t.*, ROW_NUMBER() OVER (PARTITION BY category ORDER BY t.timestamp DESC) AS rn
FROM table1 AS t)
SELECT ranked_rows.* FROM ranked_rows WHERE rn<=3
now I need to select 10 partitions from the results randomly (please notice that each partition has 3 rows). how to do that?
There are various methods. One is:
WITH ranked_rows AS (
SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY category ORDER BY t.timestamp DESC) AS seqnum,
DENSE_RANK() OVER (ORDER BY MD5(category)) as catnum
FROM table1 t
)
SELECT ranked_rows.*
FROM ranked_rows
WHERE seqnum <= 3 AND catnum <= 10;
The md5() just makes the results look random.
if you want true random per category, here is one way :
with categorycte as (
select category , rand() randomcatid
from table1
group by category
),ranked_rows AS
(
SELECT t.*
, ROW_NUMBER() OVER (PARTITION BY category ORDER BY t.timestamp DESC) AS rn
, dense_rank() over (order by randomcatid) catnum
FROM table1 AS t
join categorycte c on t.category = c.category
)
SELECT ranked_rows.* FROM ranked_rows
WHERE rn<=3 and catnum <= 10;

Distinct 2 Different Columns, How to print total combination in every row

Having this query,
SELECT DISTINCT ID, DATE FROM MAIN_TAB ORDER BY ID ASC
How can I print the total of different combinations for ID field, on the front of every row, example TOTAL_DISTINCT_VALUES:
ID DATE TOTAL_DISTINCT_VALUES
37870 02/07/2018 3
37870 03/07/2018 3
37870 04/07/2018 3
55887 04/07/2018 2
55887 03/07/2018 2
61891 02/07/2018 1
44891 02/07/2018 1
75891 02/07/2018 1
You could use count and group by
SELECT ID, DATE, count(*) TOTAL_DISINCT_VALUE
FROM MAIN_TAB
GROUP BY ID, DATE
ORDER BY ID ASC
but looking to you data sample seems you need cont only for id so you could use a join on the count group by id
select t.id, a.date, t.TOTAL_DISTINCT_VALUE
from MAIN_TAB a
inner JOIN (
select id, count(*) TOTAL_DISTINCT_VALUE
FROM MAIN_TAB
group by ID
) t on a.id = t.id
or as suggested by barmar . count(distinct date)
select t.id, a.date, t.TOTAL_DISTINCT_VALUE
from MAIN_TAB a
inner JOIN (
select id, count(distinct date) TOTAL_DISTINCT_VALUE
FROM MAIN_TAB
group by ID
) t on a.id = t.id
use group by clause
SELECT ID, DATE,count(*) as distinct_value FROM MAIN_TAB
group by ID, DATE
ORDER BY ID ASC
Try this:
select ID,DATE,count(*) as TOTAL_DISINCT_VALUE from MAIN_TAB group by ID,DATE order by ID asc;
and replace * with any other column name except ID and DATE.

Use GROUP BY and ROW_NUMBER together in query

In my query I am using rownumber to have a partition on customer id but i want it grouped by emailaddress. Is there a way to do it?
I have two tables, containing the following columns:
Customers:
EmailAddress,CustomerId
Orders:
OrderDate,CustomerId,OrderId,PaymentAmount
select
t.EmailAddress,
COUNT(t.OrderID) AS NumOrders,
SUM(t.PaymentAmount) as Total_Ordered,
max (case when t.rn = 2 then t.OrderDate end) as previous_date,
max (case when t.rn = 1 then t.Orderdate end) as last_date
from
(
select
c.EmailAddress,
o.OrderDate,
o.OrderID ,
o.PaymentAmount,
row_number() over (partition by c.CustomerID order by OrderDate desc) as rn
from
Customers c
Join Orders o
ON c.CustomerID=o.CustomerID
)t
group by
t.EmailAddress;
Note: My data is unique by EmailAddress and not by CustomerID

MAX (SUM(votes)) | get only winners

I want to get only winners in mysql table.
SELECT mayor_id, local_unit_id, Value FROM
(SELECT mayor_id, local_unit_id, SUM( `votes` ) AS 'Value'
FROM mayorresults
GROUP BY `mayor_id`) AS t1
ORDER BY `t1`.`local_unit_id` ASC
Idea is to Sum votes first then get only largest number, in this case the winner.
With this query I can get all, but not just the winners.
I want MAX(SUM(votes)) to get, but It doesn't work like this.
EDIT: I want to get winners for each localunit
eg.
local_unit_id mayor_id votes
1 25 8562
2 534 18562
Update, after the explanations:
SELECT grp.local_unit_id, grp.mayor_id, grp.Value
FROM
( SELECT local_unit_id, mayor_id, SUM( votes ) AS Value
FROM mayorresults
GROUP BY local_unit_id, mayor_id
) AS grp
JOIN
( SELECT local_unit_id, MAX(Value) AS Value
FROM
( SELECT local_unit_id, mayor_id, SUM( votes ) AS Value
FROM mayorresults
GROUP BY local_unit_id, mayor_id
) AS grp
GROUP BY local_unit_id
) AS grp2
ON grp2.local_unit_id = grp.local_unit_id
AND grp2.Value = grp.Value
ORDER BY local_unit ASC
Have you tried:
SELECT mayor_id, local_unit_id, MAX(Value) FROM
(SELECT mayor_id, local_unit_id, SUM( `votes` ) AS 'Value'
FROM mayorresults
GROUP BY `mayor_id`) AS t1
ORDER BY `t1`.`local_unit_id` ASC
You can't have the max value of a sum. You can have the max sum of a subquery.

MySQL: Is it possible to compute MAX( AVG (field) )?

My current query reads:
SELECT entry_id, user_id, cat_id, AVG( rating ) as avg_rate
FROM `entry_rate`
WHERE 1
GROUP BY entry_id
cat_id relates to different categories: 1, 2, 3 or 4
Is there a way I can find the maximum average for each user in each category without setting up an additional table? The return could potentially be 4 maximum avg_rate for each user_id
Visit the link below for example:
http://lh5.ggpht.com/_rvDQuhTddnc/S8Os_77qR9I/AAAAAAAAA2M/IPmzNeYjfCA/s800/table1.jpg
May not be the most efficient way:
select user_id, cat_id, MAX(avg_rate)
FROM (
SELECT entry_id, user_id, cat_id, AVG( rating ) as avg_rate
FROM entry_rate
GROUP BY entry_id, user_id, cat_id) t
GROUP BY user_id, cat_id
You can make this statement.
SELECT entry_id, user_id, cat_id, AVG( rating ) as avg_rate
FROM 'entry_rate'
GROUP BY entry_id
order by AVG( rating ) DESC
limit 1
this make the result order by avg(rating) and select the first row. and can make the limit 1,1 to select the second max element
SELECT s.user_id,s.cat_id,max(s.avg_rate) FROM (
SELECT entry_id, user_id, cat_id, AVG( rating ) as avg_rate
FROM entry_rate
GROUP BY entry_id,user_id,cat_id) as s
GROUP BY s.user_id,s.cat_id
SELECT entry_id, user_id, cat_id, AVG( rating ) as avg_rate
FROM entry_rate
GROUP BY entry_id
order by avg_rate desc limit 1;