I'm query max value it's duplicate values - sql-server-2008

I want query from sql server 2088 R2. But it's duplicate values​​.
I need it's not duplicate values​​.
Code:
Select es.EmpCode,es.Eff,es.Year,MAX(es.Month)
From SP_EffEmpAnalysis es
Where es.Year = '2012'
Group By es.EmpCode,es.Eff,es.Year
Order By es.EmpCode,MAX(es.Month) desc
Output
EmpCode | Eff | Year | Month
1410013 | 0 | 2012 | 11
1450021 | 0.952700018882751 | 2012 | 8
1460037 | 0.653999984264374 | 2012 | 9
1460037 | 0.809899985790253 | 2012 | 8
1460037 | 0.863600015640259 | 2012 | 7
1460047 | 0.796299993991852 | 2012 | 7
1480013 | 0 | 2012 | 11
1480080 | 0.91839998960495 | 2012 | 12
1480080 | 0.982299983501434 | 2012 | 11
1480080 | 1.08259999752045 | 2012 | 10
1480080 | 0.989700019359589 | 2012 | 9
I need ouput
EmpCode | Eff | Year | Month
1410013 | 0 | 2012 | 11
1450021 | 0.952700018882751 | 2012 | 8
1460037 | 0.653999984264374 | 2012 | 9
1460047 | 0.796299993991852 | 2012 | 7
1480013 | 0 | 2012 | 11
1480080 | 0.91839998960495 | 2012 | 12

I think what you are looking for is the last month's values per employee. You can get that with the row-number function:
SELECT EmpCdoe, Eff, Year, Month
FROM(
SELECT *,ROW_NUMBER()OVER(PARTITION BY EmpCode ORDER BY Year DESC, Month DESC) AS frn
WHERE Year = '2012'
)X
WHERE frn=1
ORDER BY EmpCode;

Sebastian typed faster, but I think this is more complete:
select EmpCode, Eff, Year, Month
from (
select es.EmpCode, es.Eff, es.Year, es.Month,
Row_Number() over ( partition by es.EmpCode order by es.Year desc, es.Month desc ) as RN
from SP_EffEmpAnalysis es
where es.Year = '2012' ) as Placeholder
where RN = 1
order By es.EmpCode

Related

MySQL Query to get the monthly data difference

select * from new_joiner;
+------+--------------+
| id | date_of_join |
+------+--------------+
| 1 | 2020-01-10 |
| 2 | 2020-01-02 |
| 3 | 2020-01-05 |
| 4 | 2020-02-10 |
| 5 | 2020-02-11 |
| 6 | 2020-07-11 |
| 7 | 2020-07-11 |
| 8 | 2020-07-11 |
| 9 | 2020-07-11 |
| 10 | 2020-07-11 |
| 11 | 2020-05-01 |
| 12 | 2020-05-02 |
| 13 | 2020-05-03 |
| 14 | 2020-05-04 |
| 15 | 2020-05-05 |
| 16 | 2020-05-05 |
| 17 | 2020-05-06 |
+------+--------------+
select MONTHNAME(date_of_join) as MONTHNAME,
count(id) as JOINEE
from new_joiner
where MONTH(date_of_join)>=1
group by MONTH(date_of_join);
+-----------+--------+
| MONTHNAME | JOINEE |
+-----------+--------+
| January | 3 |
| February | 2 |
| May | 7 |
| July | 5 |
+-----------+--------+
I want a query that gives me the monthly data change compare to previous month.
For example: new joinee in Jan was 3, and in Feb it was 2, so compare to Jan in Feb month -1 joined, so the query should output me:
+-----------+-------------+
| MONTHNAME | JOINEE_DIFF |
+-----------+-------------+
| February | -1 |
| Mar | -2 |
| April | 0 |
| May | 7 |
| June | -7 |
| July | 5 |
| Aug | -5 |
| Sep | 0 |
| Oct | 0 |
| Nov | 0 |
| Dec | 0 |
+-----------+-------------+
Ignore Jan as it doesn't have a previous month and assume we have data only for a given year say 2020. Require data for all months from Feb to Dec.
Assuming you have data for every month, you can use lag():
select MONTHNAME(date_of_join) as MONTHNAME,
count(id) as JOINEE,
(count(*) - lag(count(*)) over (order by min(date_of_join)) as diff
from new_joiner
where MONTH(date_of_join) >= 1
group by MONTH(date_of_join);
Note that using months without years if fraught with peril. Also, the month() of any well-formed date should be larger than 1.
All this suggests a query more like:
select *
from (select MONTHNAME(date_of_join) as MONTHNAME,
count(id) as JOINEE,
(count(*) - lag(count(*)) over (order by min(date_of_join)) as diff,
min(date_of_join) as min_date_of_join
from new_joiner
where date_of_join >= '2020-01-01' and date_of_join < '2021-01-01'
group by MONTH(date_of_join)
) t
where diff is not null
order by min_date_of_join;
Use a correlated subquery to get the number of joinees of previous month and subtract it:
SELECT
t.monthname,
joinee - (SELECT COUNT(*) FROM new_joiner WHERE MONTH(date_of_join) = t.month - 1) JOINEE_DIFF
FROM (
SELECT MONTH(date_of_join) month, MONTHNAME(date_of_join) monthname,
COUNT(id) joinee
FROM new_joiner
GROUP BY month, monthname
) t
WHERE t.month > 1;

How to JOIN a table based on month

I am trying to get the number of appointments for each month.
The results are grouped into each month for a rolling-12-months graph.
I have the following Query:
SELECT a.time AS appointmentdatetime,
m.text AS ref_month_text,
m.month AS ref_month_int,
YEAR(TIME) AS appointmentyear,
COUNT(a.id) AS COUNT
FROM ref_months m LEFT JOIN
appointment a
ON m.month = MONTH(a.time) AND
a.time >= DATE_ADD(NOW(), INTERVAL - 12 MONTH)
AND a.dealershipid = '1' AND a.dealerstatus != 'No-Show'
GROUP BY m.month
ORDER BY appointmentyear ASC, m.month ASC
This is the result:
+----------------+--------------------+-------+--+
| ref_month_text | appointmentyear | COUNT | |
+----------------+--------------------+-------+--+
| February | 2019 | 16 | |
| March | 2019 | 18 | |
| April | 2019 | 10 | |
| May | 2019 | 15 | |
| June | 2019 | 18 | |
| July | 2019 | 10 | |
| August | 2019 | 12 | |
| September | 2019 | 20 | |
| October | 2019 | 7 | |
| November | 2019 | 13 | |
| December | 2019 | 7 | |
| January | 2020 | 11 | |
+----------------+--------------------+-------+--+
The grouping by month, on a rolling-12-months, and showing null when no data, is what I am getting, but the issue I am having is that the count is wrong for each month.
Eg. March 2019 should be 20.
I have tried all variations of JOIN types. But still returning wrong figures.
I simplified your query
SELECT
YEAR(a.time) AS year,
ANY_VALUE(MONTHNAME(a.time)) AS month,
ANY_VALUE(COUNT(a.id)) AS counter,
MONTH(a.time) AS mo
FROM
appointment AS a
GROUP BY
year,mo
ORDER BY
year ASC,
mo ASC

MySQL: Tagging 1 to each unique occurence during SELECT query

Sample table tbl_name:
| ID | Name | Month | Quarter | Year |
| 1 | A | Jan | 1 | 2019 |
| 1 | A | Feb | 1 | 2019 |
| 2 | B | May | 2 | 2019 |
| 3 | C | May | 2 | 2018 |
Hi, this is the table I extract using SELECT query. I can find the distinct name per year using SELECT distinct name, year FROM tbl_name; But I'm trying to add a column during SELECT query to identify or count the unique occurrence per year of the name.
Expected:
| ID | Name | Month | Quarter | Year | Unique Count |
| 1 | A | Jan | 1 | 2019 | 1 |
| 1 | A | Feb | 1 | 2019 | 0 |
| 2 | B | May | 2 | 2019 | 1 |
| 3 | C | May | 2 | 2018 | 1 |
I tried splitting into two queries - one select everything; the other select just distinct and join them together but that will introduce duplicates. Is there a way to do this using SQL?
If you are running MySQL 8.0, you can use row_number() to flag the appearance of a name in a year:
select
t.*,
(row_number() over(
partition by name, year
order by str_to_date(concat(year, '-', month), '%Y-%b')
) = 1) unique_count
from mytable t
Note: do consider fixing the storage strategy of your date columns. Rather than splitting the information over several columns, you would better have a unique column in the relevant DATE datatype to store that information. That would save you the pain of recomposing the date when you need it.
Demo on DB Fiddle:
ID | Name | Month | Quarter | Year | unique_count
-: | :--- | :---- | ------: | ---: | -----------:
1 | A | Feb | 1 | 2019 | 1
1 | A | Jan | 1 | 2019 | 0
2 | B | May | 2 | 2019 | 1
3 | C | May | 2 | 2018 | 1
You can try this below logic-
DEMO HERE
WITH your_table(ID,Name,Month,Quarter,Year)
AS
(
SELECT 1,'A','Jan',1,2019 UNION ALL
SELECT 1,'A','Feb',1,2019 UNION ALL
SELECT 2,'B','May',2,2019 UNION ALL
SELECT 3,'C','May',2,2018
)
,CTE AS
(
SELECT *,ROW_NUMBER() OVER(PARTITION BY ID ORDER BY Quarter,Year) RN
FROM your_table
)
SELECT ID,Name,Month,Quarter,Year,
CASE WHEN RN = 1 THEN 1 ELSE 0 END Unique_Count
FROM CTE
Output is-
ID Name Month Quarter Year Unique_Count
1 A Jan 1 2019 1
1 A Feb 1 2019 0
2 B May 2 2019 1
3 C May 2 2018 1

Displaying groups having max number of occurence

t_table looks like:
+-----------+---------+--------------+------------------+-----------------------+----------------------------------+
| pk_IdLoan | fk_IdCar| fk_IdCustomer| fk_Source_Agency | fk_Destination_Agency | RentalDate | DeliveryDate | Cost |
+-----------+---------+--------------+------------------+-----------------------+----------------------------------+
I wrote a query:
(SELECT fk_IdCustomer, MONTHNAME(RentalDate) AS Month, YEAR(RentalDate) As Year, COUNT(*)
FROM t_loan
GROUP BY fk_IdCustomer, Month, Year);
which results in
+---------------+-------------+------+----------+
| fk_IdCustomer | Month | Year | COUNT(*) |
+---------------+-------------+------+----------+
| 1 | July | 2016 | 3 |
| 1 | November | 2017 | 1 |
| 1 | September | 2016 | 7 |
| 5 | May | 2016 | 1 |
| 6 | January | 2016 | 1 |
| 6 | September | 2017 | 2 |
+---------------+-------------+------+----------+
Now I want to get these months and years for each customer which result in highest COUNT(*), f.e.:
+---------------+-------------+------+----------+
| fk_IdCustomer | Month | Year | COUNT(*) |
+---------------+-------------+------+----------+
| 1 | September | 2016 | 7 |
| 5 | May | 2016 | 1 |
| 6 | September | 2017 | 2 |
+---------------+-------------+------+----------+
How to achieve this?
This is a bit painful in MySQL, which doesn't support CTEs or window functions. One method is:
SELECT fk_IdCustomer, MONTHNAME(RentalDate) AS Month,
YEAR(RentalDate) As Year, COUNT(*) as cnt
FROM t_loan l
GROUP BY fk_IdCustomer, Month, Year
HAVING cnt = (SELECT COUNT(*)
FROM t_loan l2
WHERE l2.fk_IdCustomer = l.fk_IdCustomer
GROUP BY MONTHNAME(RentalDate), YEAR(RentalDate)
ORDER BY COUNT(*) DESC
LIMIT 1
);
Note: If there are duplicates, you will get all matching values.

Getting average of one column in a nested SQL query

I'll try to simplify this for simplicity's sake. I need to get the average value of a returned column of a query. Make sense? I'll try to elaborate.(Sample results borrowed from another question)
Plant_ID | Year |Quarter| MR | Range
| CCAR | 2009 | 1 | 706 | Null
| CCAR | 2009 | 2 | 626 | 0,08
| CCAR | 2009 | 2 | 637 | 0,11
| CCAR | 2009 | 2 | 737 | 0,1
| CCAR | 2009 | 1 | 552 | 0,19
| CCAR | 2009 | 4 | 418 | 0,137
| CCAR | 2009 | 1 | 503 | 0,085
| CCAR | 2009 | 2 | 645 | 0,058
| CCAR | 2009 | 4 | 743 | 0,098
| CCAR | 2009 | 3 | 556 | 0,187
| CCAR | 2009 | 1 | 298 | 0,258
| CCAR | 2009 | 2 | 339 | 0,041
| CCAR | 2010 | 1 | 381 | 0,042
I would get this result when I run a query like this
Select PlantID, Year, Quarter, MR, Range FROM TestTable WHERE PlantID in('CCAR')
I want the average MR for each quarter. Preliminarily I would try something like this.
Select Quarter, AVG(MR) FROM (Select PlantID, Year, Quarter, MR, Range FROM TestTable WHERE PlantID in ('CCAR')) GROUP BY Quarter ORDER BY Quarter
The issue is that I don't know where to nest the query to accomplish this. Any help?
Thanks!
Add an alias e.g. hallo
Select Quarter, AVG(MR) FROM
(Select PlantID, Year, Quarter, MR, Range FROM TestTable WHERE PlantID in ('CCAR')) hallo
GROUP BY Quarter ORDER BY Quarter
while this is not necessary in this case, the following would be enough
Select Quarter, AVG(MR)
FROM TestTable
WHERE PlantID in ('CCAR')
GROUP BY Quarter
ORDER BY Quarter
Just use aggregation:
select Year, Quarter, avg(MR)
from TestTable
where PlantID in ('CCAR')
group by Year, Quarter;
I presume you want the year with the quarter. If not, just remove year from the select and group by.