Select unique combination from a table in Mysql - mysql

My dataset has the following format;
Student_id Month Year Amount
1 Jan 2010 600
1 Feb 2010 391
1 Apr 2010 673
1 Jul 2010 564
5 Jan 2010 789
5 Mar 2011 298
5 Aug 2010 347
7 Jan 2010 654
7 Dec 2011 621
7 Apr 2010 450
7 Nov 2011 980
... & so on.
I wish my output which will have max amount for each unique id-month-year combination. Viz,
Student_id Month Year Amount
1 Apr 2010 673
5 Jan 2010 789
7 Nov 2011 980
... & like this.
How to get the output using SQL? I tried
select distinct * , MAX(Amount) from student_details;
&
SELECT *, MAX(Amount)
FROM student_details
WHERE Amount IN
(
FROM student_details
GROUP BY Student_ID, Year, Month
);
but the output is not as desired.
Please suggest assistance. Thanks in advance.

In MySQL:
SELECT t0.*
FROM student_details AS t0
LEFT JOIN student_details AS t1 ON t0.Student_id=t1.Student_id t1.Amount>t0.Amount
WHERE t1.Student_id IS NULL;
In SQL server:
SELECT T.Student_id,T.Month,T.Year,T.Amount
FROM
(
SELECT *,row_number() over (PARTITION BY Student_ID ORDER BY Amount DESC) as RN
FROM student_details
)T
WHERE T.RN=1

Simply use below query
first select amount month for each user then select data which has selected month
SELECT * FROM table WHERE amount IN (
SELECT max(amount) FROM table group by student_id
)

Related

How to calculate the rank in mysql

I need to calculate the rank in mysql. Suppose I have list of sum of my product sales values of entire month then i need to rank the product from highest sales value in order to rank like 1 ,2 ,3 etc
Month Product Sum of Sales
Jan Latop 450000
jan Latop 150000
Jan Latop 250000
Feb Desktop 200000
Feb Desktop 150000
Feb Desktop 180000
so from above data output will be like
Month Product Sum of Sales rank
Jan Latop 450000 1
Jan Latop 250000 2
jan Latop 150000 3
Feb Desktop 200000 1
Feb Desktop 180000 2
Feb Desktop 150000 3
You can do something like this:
SELECT month,product,sumOfSales, #curRank := #curRank + 1 AS rank
FROM products p, (
SELECT #curRank := 0
) q
ORDER BY sumOfSales DESC;
I am assuming the table name is product and column name is sumOfSales.
You Can use this Query
SELECT sales FROM TABLE Order by sales DESC
sales is your column name where sum of sale is stored
Query Will Return Record with most sales first and so on.

Which phone has got high sales in each year?

I have a table in mysql. How to write the query to find the phone name that has got highest sales(highest number of Sold_out in each year)
--------------------------------------------
Phone Sold_out Month Year
--------------------------------------------
iphone 3 Jan-15 2015
iphone 10 Feb-15 2015
samsung 4 March-15 2015
Lava 14 June-16 2016
Lenova 8 July-16 2016
Lenova 10 Sep-16 2016
Motorola 8 Jan-17 2017
Nokia 7 Jan-17 2017
Nokia 3 Feb-17 2017
--------------------------------------------
The result I need is
-----------------------------
year Phone sales
-----------------------------
2015 iphone 13
2016 lenova 18
2017 Nokia 10
-----------------------------
In the derived table the total sales are calculated at ( year,phone ) combination. Once the total sales are calculated all the top rows( rank = 1 by sales ) should be identified for each year. By using correlated sub-queries and having clause the first row is identified from each group( year ) and displayed as final output.
SELECT year,phone, sales_per_year
FROM
(
SELECT year,phone,SUM(sold_out) AS sales_per_year
FROM sales
GROUP BY year,phone
) o
GROUP BY year,phone
HAVING (
SELECT COUNT(*)
FROM
(
SELECT year,phone,SUM(sold_out) AS sales_per_year
FROM sales
GROUP BY year,phone
) i
WHERE i.year = o.year
AND i.sales_per_year > o.sales_per_year
) < 1
ORDER BY year,phone,sales_per_year DESC
Check the sql fiddle link
http://sqlfiddle.com/#!9/ff096e/14

how can i show sql header columns in rows in sql server

i want to show these records column wise for particular month and year, like below table format
Source Total
Organic 1252
Paid 121
Email Campaign 121
Total 1494
select Organic,Paid ,EmailCampaign ,Total from tbl_leads where Month='Aug' and Year='2015'
below is sample date
Organic Paid EmailCampaign Total ProjectName Month Year
4444 5555 2222 1111 demo project Feb 2015
1252 121 121 1494 debug test Aug 2015
In Sql Server you can use Cross Apply with Tabled Valued Constructor to unpivot the data
SELECT cs.Source,
cs.Total
FROM tbl_leads
CROSS apply (VALUES ('Organic',Organic),
('Paid',Paid),
('EmailCampaign',EmailCampaign),
('Total',Total)) cs(Source, Total)
WHERE Month = 'Aug'
AND Year = '2015'
Or Generic Sql solution
SELECT 'Organic' AS Source,
Organic AS Total
FROM tbl_leads
UNION ALL
SELECT 'Paid',
Paid
FROM tbl_leads
UNION ALL
SELECT 'EmailCampaign',
EmailCampaign
FROM tbl_leads
UNION ALL
SELECT 'Total',
Total
FROM tbl_leads

Employee Year Calculation

I have employees table with date_of_join field
and I have employee_leaves table with the following fields:
employee_id
leave_from
leave_to
total_days
the employee joined on 15 Feb 2011
I want to have a query showing the cound of leaves for every employee years based on his date_of_join
for example, if the employee joined on 15 Feb 2011 then the result will be like this:
Feb 2011 to feb 2012 ---- totals days: 21
Feb 2012 to feb 2013 ---- totals days: 26
Feb 2013 to feb 2014 ---- totals days: 8
where Feb to feb is the employee year so it's from 15 Feb to 14 Feb every year
can anyone help please?
Not having your data it is difficult to test this but I came up with the following based on your description:
SELECT employees.employee_id, DATE_ADD(employees.date_of_join, INTERVAL yrs.years) frm
,DATE_ADD(employees.date_of_join, INTERVAL yrs.years + 1) too,
SUM(employee_leaves.total_days)
FROM employee_leaves
INNER JOIN (SELECT 0 years UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) yrs
ON 1=1
INNER JOIN employees ON employee_leaves.employee_id = employees.employee_id
AND employee_leaves.leave_from BETWEEN DATE_ADD(employees.date_of_join, INTERVAL yrs.years) AND DATE_ADD(employees.date_of_join, INTERVAL yrs.years + 1)
GROUP BY employees.employee_id, DATE_ADD(employees.date_of_join, INTERVAL yrs.years)
;
Probably needs some fiddling, hope this helps.

Finding AVG value in SQL Query after SUM - Invalid use of group function

I have some query which works fine for me:
Select Name,sum(number_hours)/8)*100
from
T1
where name='PERSON_A'
group by name,booked_date
Name is always ONE same person which I put in where clause.Result will be:
PERSON_A 100
PERSON_A 140
PERSON_A 120
This is calculating some daily utilization for workers for each booked date.
Now I want to calculate AVERAGE daily utilization((120+120+100)/3=120)
But when I put
Select Name,AVG(sum(number_hours)/8)*100)
FROM
T1
WHERE name='PERSON_A'
group by name,booked_date
I am getting error Invalid use of group function. Why? How can I calculate average value after summuryzing values for daily utilization.
Thanks
Try using a subquery for the sum and calculate the average in the outer query, like in:
SELECT Name, AVG (hsum)
FROM
(
SELECT Name,sum((number_hours)/8)*100 AS hsum
FROM
T1
WHERE name='PERSON_A'
GROUP BY name,booked_date
) t
I understand you already have accepted the answer. But give this a try too :) No subquery. Quite fast too. I added extra Count of workdates column for you to see the dates.
* SQLFIDDLE DEMO
Sample data table:
ID NAME HOURS WORKDATE
100 j 20 December, 03 2012 00:00:00+0000
200 k 10 December, 03 2012 00:00:00+0000
100 j 10 December, 04 2012 00:00:00+0000
300 l 20 December, 04 2012 00:00:00+0000
100 j 5 December, 05 2012 00:00:00+0000
300 l 15 December, 03 2012 00:00:00+0000
100 j 10 December, 04 2012 00:00:00+0000
400 m 20 December, 03 2012 00:00:00+0000
Query:
SELECT Name, ((sum(hours)/8)*100) AS sum
,count(distinct workdate) workdates, ((sum(hours)/8)*100)/count(
distinct workdate) as avg
FROM
works
WHERE name='j'
GROUP BY name
;
Results:
NAME SUM WORKDATES AVG
j 562.5 3 187.5