Get last diploma for each employee - sql-server

I want to get the last diploma for each employee :
SELECT * FROM (SELECT e.employeeid,afd.AdminFileId ,afd.Title,ss.Name,YearObtained,afd.CreateDate,
ROW_NUMBER() OVER (PARTITION BY afd.AdminFileId ORDER BY afd.CreateDate desc) AS rn
FROM AF_Degree afd
LEFT JOIN AF_AdminFile aaf ON afd.AdminFileId = aaf.AdminFileId
LEFT JOIN schools_School ss ON afd.SchoolId = ss.ID
LEFT JOIN employee e ON e.adminfileid=aaf.AdminFileId) AS D WHERE D.employeeid=109
The result of the above query :
Case of EmployeeId= 109 :
employeeid AdminFileId Title School YearObtained CreateDate
107 149971 Intercambio universitario; Programa Erasmus ( meses) Universidad Politécnica de Cartagena 2008 2018-05-14 03:45:41.6436995
107 149971 Student exchange Umeå University 2008 2018-06-27 16:01:53.8213765
107 149971 Erasmus Program (12months) POLITECNICA CARTAGENA 2006 2018-06-27 16:01:53.8213765
Case of EmployeeId= 139 :
employeeid AdminFileId Title School YearObtained CreateDate
139 145555 Electronic Business Engineering Czech University of Life Sciences Prague 2007 2018-05-14 03:45:41.6436995
139 145555 Entrepreneurship and Management Umeå University 2009 2015-06-23 17:30:31.3100000
139 145555 Ingeniería técnica en informática de gestión Czech University of Life Sciences Prague 2009 2015-06-23 17:30:31.3100000
For EmoloyeeId=109 the expected result is :
EmployeeId AdminFileId Title School YearObtained CreateDate
107 149971 Student exchange Umeå University 2008 2018-06-27 16:01:53.8213765
For EmoloyeeId=139 the expected result is :
EmployeeId AdminFileId Title
139 7198 Ingeniería técnica en informática de gestión Czech University of Life Sciences Prague 2009 2015-06-23 17:30:31.3100000
How to get the last diploma obtained for an employee based on the YearObtained and the CreateDate especially when we have two diplomas in the same year and having the same CreateDate like in the two cases mentioned above and their related expected output ?

Just add WHERE d.rn = 1 to the outer query. Also may need to change the partition just a bit to ... ORDER BY YearObtained DESC, afd.CreateDate DESC)...
SELECT *
FROM (
SELECT e.employeeid,afd.AdminFileId ,afd.Title,ss.Name,YearObtained,afd.CreateDate,
ROW_NUMBER() OVER (PARTITION BY afd.AdminFileId ORDER BY afd.CreateDate desc) AS rn
FROM AF_Degree afd
LEFT JOIN AF_AdminFile aaf ON afd.AdminFileId = aaf.AdminFileId
LEFT JOIN schools_School ss ON afd.SchoolId = ss.ID
LEFT JOIN employee e ON e.adminfileid=aaf.AdminFileId
) AS D
WHERE d.rn = 1
That will get you one row. However, if there's the same YearObtained and CreateDate then it's not guaranteed which record you will get. You may need to add a third column to the ORDER BY in the partition such as an ID or something unique.

Related

Snowflake Unable to get the hierarchy columns values

I have below table from which i am trying to get the correspondent manager name against the employee
TITLE EMPLOYEE_ID MANAGER_ID
President 1
Vice President Engineering 10 1
Programmer 100 10
QA Engineer 101 10
Vice President HR 20 1
Health Insurance Analyst 200 20
i used below hierarchy query to get the result
select employee_id, manager_id, title, prior report_title
from employees
start with title = 'President'
connect by
manager_id = prior employee_id
order by employee_id;
But result not returning as i expected
Expected:
EMPLOYEE_ID MANAGER_ID title report_title
10 1 Vice President Engineering President
Can anyone help on this?
If you use a recursive CTE, you can get the output you want.
with emptree as
(select employee_id, title, manager_id, null as report_title
from employees
where manager_id is null
union all
select employees.employee_id, employees.title, employees.manager_id, emptree.title
from employees
join emptree
on employees.manager_id = emptree.employee_id
)
select employee_id, manager_id, title, report_title
from emptree
order by employee_id;
EMPLOYEE_ID
MANAGER_ID
TITLE
REPORT_TITLE
1
NULL
President
10
1
Vice President Engineering
President
20
1
Vice President HR
President
100
10
Programmer
Vice President Engineering
101
10
QA Engineer
Vice President Engineering
200
20
Health Insurance Analyst
Vice President HR

SQL Server - Apply OrderBy on columns when used CAST()

In my gaming application i have Teams and each Team can have any number of players, if a player participates in a match i am giving him 5 points. Each time the player participates in a match he will get 5 points added to his count.
my stored procedure takes TeamId as the input parameter.
Now i want to calculate the Total Participation points each team has got by month, but here the Participation Points each player has scored should be added to the last month in which the player has played the Match.
Lets say Team1 has Player1 and player1 has played total of 4 matches, 1 match in 04/2020 , 2 matches in 06/2020 and 1 match in 08/2020 , here for playing 4 matches Player1 of Team1 got 20 participation points and the last match Player1 played is in 08/2020 so all the 20 points should be added to 08/2020 for Team1
In the player table across each Player i have a [TotalMatchesPlayed] by each player, [TotalMatchesPlayed] * 5 will give me the [TotalParticipationPoints] for each player.
This should repeat for all the players in the Team.
SELECT DISTINCT TP.[TeamId], ISNULL(P.[TotalMatchesPlayed], 0) * 5 AS [ParticipationPoints], CAST(MONTH(PA.[ActivityDate]) AS VARCHAR(2)) AS [Month], CAST(YEAR(PA.[ActivityDate]) AS VARCHAR(4)) AS [Year] FROM [TeamPlayers] TP
INNER JOIN dbo.[Player] P
ON TP.[PlayerId] = P.[PlayerId]
INNER JOIN dbo.[PlayerActivity] PA
ON PA.[PlayerId] = P.[PlayerId] AND PA.[ActivityTypeId] = 14
WHERE TP.[TeamId] = 12
my issue with above query is [PlayerActivity] table has a row each time a player participates in a match, now i want to take only the latest date and add all the participation points to that month and year which i am not able to achieve
I tried adding ORDER BY PA.[ActivityDate] DESC but thts throwing an error
Order by items must appear in the select list if SELECT DISTINCT is
specified.
my sample output should be as below
ParticipationPoints | Month | Year
50 03 2020
0 04 2020
20 05 2020
sample table designs and data in the below link.
http://sqlfiddle.com/#!18/41766/1
Does this work for you:
SELECT
TP.[TeamId]
, SUM(ISNULL(P.[TotalMatchesPlayed], 0)) * 5 AS [ParticipationPoints]
, DATEPART(MONTH,PA.[ActivityDate]) AS [Month]
, DATEPART(YEAR,PA.[ActivityDate]) AS [Year]
FROM [TeamPlayer] TP
INNER JOIN dbo.[Player] P
ON TP.[PlayerId] = P.[PlayerId]
INNER JOIN dbo.[PlayerActivity] PA
ON PA.[PlayerId] = P.[PlayerId] AND PA.[PlayerActivityTyepId] = 14
WHERE TP.[TeamId]=45
GROUP BY TP.[TeamId], DATEPART(MONTH,PA.[ActivityDate]), DATEPART(YEAR,PA.[ActivityDate])
ORDER BY DATEPART(MONTH,PA.[ActivityDate]) DESC, DATEPART(YEAR,PA.[ActivityDate]) DESC
You called some [Activity Date] fields so you should select one of the casts above as order by
SELECT DISTINCT TP.[TeamId], ISNULL(P.[TotalMatchesPlayed], 0) * 5 AS [ParticipationPoints], CAST(MONTH(PA.[ActivityDate]) AS VARCHAR(2)) AS [Month], CAST(YEAR(PA.[ActivityDate]) AS VARCHAR(4)) AS [Year] FROM [TeamPlayers] TP
INNER JOIN dbo.[Player] P
ON TP.[PlayerId] = P.[PlayerId]
INNER JOIN dbo.[PlayerActivity] PA
ON PA.[PlayerId] = P.[PlayerId] AND PA.[ActivityTypeId] = 14
WHERE TP.[TeamId] = 12
ORDER BY CAST(MONTH(PA.[ActivityDate]) AS VARCHAR(2)) desc

Getting customer name based on lowest order from 2 tables

I am a beginner learning SQL. I have 2 tables. Trying to get the customer first and last name with least transaction amount - only that 1 row. Been trying different code all day but getting nowhere.
Table 1: Orders
Customer_Id TxnDate Amount
-------------------------------
4001 21-Aug-18 245.99
4002 30-Jan-18 49.99
4003 15-Apr-17 204.87
4001 18-Dec-18 130.88
4004 15-May-17 198.33
4006 4-Feb-17 783.65
Table 2: Customers
Customer_Id AcctOpenDate CustomerFirstName CustomerLastName
--------------------------------------------------------------
4001 7-Jan-16 John Doe
4002 15-Apr-15 Ashley Smith
4003 14-May-14 Carter Jones
4004 17-Sep-16 Ika Gaut
4005 18-Aug-14 Gray Show
4006 25-Oct-15 Kathia Kim
Query:
SELECT
C.CustomerFirstName, C.CustomerLastName, O.Amount
FROM
Customers C
WHERE
Amount = (SELECT MIN(Amount) FROM Orders) Leasttxnamt
INNER JOIN
Customers C ON O.Customer_Id = C.Customer_Id;
Current error produced:
Msg 102, Level 15, State 1, Line 31
Incorrect syntax near 'Leasttxnamt'
Try this..
returns first and last name of customers with lowest transaction amount
select CustomerFirstName,CustomerLastName
from Customer
where Customer_Id in (
SELECT DISTINCT Customer_Id
from Orders
where Amount=(select min(Amount) from orders))
If I understand correctly, you are looking for customer wise MIN amount from the Order table. If this is correct, you can use the following script for your purpose-
This is workable in most of the databases.
SELECT C.CustomerFirstName, C.CustomerLastName, MIN(Amount) min_amount
FROM Customers C
LEFT JOIN Orders O ON O.Customer_Id = C.Customer_Id
GROUP BY C.CustomerFirstName, C.CustomerLastNam
Try the following query :
SELECT Customers.CustomerFirstName ,Customers.CustomerLastName
FROM Customers
JOIN Orders ON Customers.Customer_Id = Orders.Customer_Id
AND Orders.Amount=(
SELECT min(Amount) FROM Orders
WHERE Customers.Customer_Id = Orders.Customer_Id
)

Return sum of data from Column A and corresponding Name from column B using SQL Server

This is a bit tricky situation. I'm using the T-SQL language.
My current data in SQL Server is: there are seminars and multiple BDMs under each seminar who can book multiple opportunities.
I need the total of "Oppty Booked" per seminar but only the name of BDM who has made the highest booking.
This the current data
Seminar BDM Name Oppty Booked
--------------------------------
Broome Ian 6
Broome Nas 5
Broome Kit 4
Broome Fred 0
Gympie Sam 16
Gympie Amanda 2
Gympie Lidcombe 4
What I need is: Required Output
Seminar BDM Name Oppty Booked
--------------------------------
Broome Ian 15
Gympie Sam 22
What can I do to get this?
You can use below query. Read about RANK.
CREATE TABLE #Test
(
Seminar VARCHAR(100),
BDM_Name VARCHAR(100),
Oppty_Booked int
)
insert into #TEst values
('Broome', 'Ian',6)
,('Broome', 'Nas',5)
,('Broome', 'Kit',4)
,('Broome', 'Fred',0)
,('Gympie', 'Sam',16)
,('Gympie', 'Amanda',2)
,('Gympie', 'Lidcombe',4)
select * from #Test
select Seminar, BDM_Name, Oppty_Booked
from
(
select
Seminar,
BDM_Name,
Rank() OVER (partition by Seminar order by Oppty_Booked desc) as RN,
SUM(Oppty_Booked)OVER (partition by Seminar ) as Oppty_Booked
from #Test
) t
where t.rn=1
Perhaps another option
Example
Select Top 1 with ties
Seminar
,[BDM Name]
,[Oppty Booked] = sum([Oppty Booked]) over (Partition By Seminar)
From YourTable
Order By Row_Number() over (Partition By Seminar Order By [Oppty Booked] desc)
Returns
Seminar BDM Name Oppty Booked
Broome Ian 15
Gympie Sam 22

Displaying all columns in SQL and also sum of columns with same ID in the last Repeating row

I have 2 tables
OrderDetails:
Id Name type Quantity
------------------------------------------
2009 john a 10
2009 john a 20
2010 sam b 25
2011 sam c 50
2012 sam d 30
ValueDetails:
Id Value
-------------------
2009 300
2010 500
2011 200
2012 100
I need to get an output which displays the data as such :
Id Name type Quantity Price
-------------------------------------------------
2009 john a 10
2009 john a 20 9000
2010 sam b 25
2011 sam c 50
2012 sam d 30 25500
The price is calculated by Value x Quantity and the sum of the values is displayed in the last repeating row of the given Name.
I tired to use sum and group by but I get only two rows. I need to display all 5 rows. How can I write this query?
You can use Row_Number with max of Row_Number to get this formatted sum
;with cte as (
select od.*, sm= sum( od.Quantity*vd.value ) over (partition by Name),
RowN = row_number() over(partition by Name order by od.id)
from #yourOrderDetails od
inner join #yourValueDetails vd
on od.Id = vd.Id
)
select Id, Name, Type, Quantity,
case when max(RowN) over(partition by Name) = row_number() over(partition by Name order by Id)
then sm else null end as ActualSum
from cte
Your input tables:
create table #yourOrderDetails (Id int, Name varchar(20), type varchar(2), Quantity int)
insert into #yourOrderDetails (Id, Name, type, Quantity) values
(2009 ,'john','a', 10 )
,(2009 ,'john','a', 20 ) ,(2010 ,'sam ','b', 25 )
,(2011 ,'sam ','c', 50 ) ,(2012 ,'sam ','d', 30 )
create table #yourValueDetails(Id int, Value Int)
insert into #yourValueDetails(Id, value) values
( 2009 , 300 ) ,( 2010 , 500 )
,( 2011 , 200 ) ,( 2012 , 100 )
SELECT a.ID,
a.Name,
a.Type,
a.quantity,
price = (a.quantity * b.price)
FROM OrderDetails a LEFT JOIN
ValueDetails b on a.id = b.id
This will put the price on every row. If you want to do a SUM by Id,Name and Type it's not going to show the individual records like you show them above. If you want to put a SUM on one of the lines that share the same Id, Name and Type then you'd need a rule to figure out which one and then you could probably use a CASE statement to decide on which line you want to show the SUM total.

Resources