I'm having a hard time making the following to work:
I have a list of transactions consisting of Sender,Recipient, Amount and Date.
Table: Transactions
Sender Recipient Amount Date
--------------------------------------------------
Jack Bob 52 2019-04-21 11:06:32
Bob Jack 12 2019-03-29 12:08:11
Bob Jill 50 2019-04-19 24:50:26
Jill Bob 90 2019-03-20 16:34:35
Jill Jack 81 2019-03-25 12:26:54
Bob Jenny 53 2019-04-20 09:07:02
Jack Jenny 5 2019-03-29 06:15:35
Now I want to list the people who have participated in transactions, how many transactions they have participated in and the dates of the first and last transaction they participated in :
Result
Person NUM_TX First_active last_active
------------------------------------------------------------------
Jack 4 2019-03-25 12:26:54 2019-04-21 11:06:32
Bob 5 xxxx-xx-xx xx:xx:xx xxxx-xx-xx xx:xx:xx
Jill 3 xxxx-xx-xx xx:xx:xx xxxx-xx-xx xx:xx:xx
Jenny 2 xxxx-xx-xx xx:xx:xx xxxx-xx-xx xx:xx:xx
Using a group by statement seems not right - what is the right way to achieve my goal? I'm running on a postgres btw.
You need a UNION to get the 2 columns as 1 column person of a resultset and then group by person:
select
t.person Person,
count(*) NUM_TX,
min(t.date) First_active,
max(t.date) Last_active
from (
select sender person, date from transactions
union all
select recipient person, date from transactions
) t
group by t.person
This is a good place to use a lateral join:
select v.person, count(*) as num_transactions,
min(t.date) as first_date,
max(t.date) as last_date
from transactions t cross join lateral
(values (sender), (recipient)) v(person)
group by v.person;
Related
I was wondering if someone could help me with this. Here is a sample set of my data:
FirstName LastName Department Ticket Hours Shift DateWorked Key
Bob Smith Sleeves 23235 4 1 2017-01-01 001
Bob Smith Sleeves 12345 4 1 2017-01-01 001
Jim Bo Sleeves 12345 8 1 2017-01-01 002
Janet Moore Lids 78945 8 2 2017-01-01 003
Jon Bob Lids 45621 1.5 3 2017-01-01 004
Jon Bob Lids 45621 7.5 3 2017-01-01 004
Bob Smith Mugs 12345 8 1 2017-01-02
Jim Bo Lids 99999 8 3 2017-01-02
It should return something like this:
DateWorked Shift Department HeadCount
2017-01-01 1 Sleeves 2 (Bob Smith has two entries but counted as one and Jim Bo makes for 2)
2017-01-01 2 Lids 1 (Janet)
2017-01-01 3 Lids 1 (Jon)
Please note that all departments work all shifts. This is just a sample set. There can be anywhere from none to a hundred per department.
Also one employee could work multiple departments in one day! I don't know how to account for that.
This is what I have. So for this example it's not summing Bob Smith. It's counting him as two.
SELECT Scheduled, Department, [Shift], COUNT(*) as HeadCount
FROM EmployeeTickets
WHERE Scheduled >= '2017-01-01' AND Scheduled < '2017-12-31'
GROUP BY Scheduled, Department, [Shift]
ORDER BY Scheduled, Department, [Shift]
Thank you.
ETA I don't know if it helps but in the table there is a key per entry, so Bob Smith on Jan 1 would have a key for that day. His social security number is also in there. I'm trying to group by one of those somehow.
just use DISTINCT
SELECT Scheduled, Department, [Shift], COUNT( DISTINCT FirstName ) as HeadCount
FROM EmployeeTickets
WHERE Scheduled >= '2017-01-01' AND Scheduled < '2017-12-31'
GROUP BY Scheduled, Department, [Shift]
ORDER BY Scheduled, Department, [Shift]
Of course this will have problem if you have multiple persons with same name. So I hope you have some EmployeeID on your tables, so you can differentiate every employee.
COUNT(DISTINCT EmployeeID)
I have a table as follows:
Name Customer Date Amount
Joe Aaron 2012-01-03 14:12:00.0 150
Joe Aaron 2012-02-03 14:12:00.0 150
Joe Danny 2012-03-03 14:12:00.0 150
Joe Karen 2012-07-03 14:12:00.0 150
Ronald Blake 2012-05-03 14:12:00.0 1501
I would like to query to retrieve data by specifying the Name and if there are duplicates for Customer column, the records for the latest Date is
For example, if I want to query Joe, I will get the following result:
Name Customer Date Amount
Joe Aaron 2012-02-03 14:12:00.0 150
Joe Danny 2012-03-03 14:12:00.0 150
Joe Karen 2012-07-03 14:12:00.0 150
How should I do this? Tried distinct but it doesnt work that way.
EDIT
I'm using SQL Server. Sorry I re-edit my question and this should be the correct question that I am asking.
Did you Try this?
SELECT Name, Customer, MAX(Date) as CurrentDate, Amount
FROM data
Group By Name, Customer, Amount
HAVING Name = 'Joe'
Another option is using the WITH TIES clause in concert with Row_Number()
Example
Select top 1 with ties *
From YourTable
Where Name='Joe'
Order By Row_Number() over (Partition By Customer Order By Date Desc)
Returns
Name Customer Date Amount
Joe Aaron 2012-02-03 14:12:00.000 150
Joe Danny 2012-03-03 14:12:00.000 150
Joe Karen 2012-07-03 14:12:00.000 150
One option:
SELECT * FROM Table WHERE (NAME, CUSTOMER, DATE) IN (SELECT NAME, CUSTOMER, MAX(DATE) WHERE NAME = 'Joe' GROUP BY NAME, CUSTOMER)
player team start_date end_date points
John Jacob SportsBallers 2015-01-01 2015-03-31 100
John Jacob SportsKings 2015-04-01 2015-12-01 115
Joe Smith PointScorers 2014-01-01 2016-12-31 125
Bill Johnson SportsKings 2015-01-01 2015-06-31 175
Bill Johnson AllStarTeam 2015-07-01 2016-12-31 200
The above table has many more rows. I was asked the below questions in an interview.
1.)For each player, which team were they play for on 2015-01-01?
I could not answer this one.
2.)For each player, how can we get the team for whom they scored the most points?
select team from Players
where points in (select max(points) from players group by player).
Please, solutions for both.
1
select *
from PlayerTeams
where startdate <='2015-01-01' and enddate >= '2015-01-01'
2
Select player, team, points
from(
Select *, row_number() over (partition by player order by points desc) as rank
From PlayerTeams) as player
where rank = 1
For #1:
Select Player
,Team
From table
Where '2015-01-01' between start_date and end_date
For #2:
select t.Player
,t.Team
from table t
inner join (select Player
,Max(points)
from table
group by Player) m
on t.Player = m.Player
and t.points = m.points
I have the following records. It is broken based on username, date and testscore.
Username date testscore
mike 2016-11-30 23:41:10.143 1
mike 2016-11-27 23:41:11.143 12
mike 2016-11-24 23:41:11.143 16
john 2016-11-28 23:41:11.143 7
john 2016-11-25 23:42:11.143 12
john 2016-11-25 23:42:11.143 7
mike 2016-10-30 23:41:10.143 1
mike 2016-10-27 23:41:11.143 5
mike 2016-10-24 23:41:11.143 16
john 2016-10-28 23:41:11.143 12
john 2016-10-25 23:42:11.143 8
john 2016-10-24 23:42:11.143 2
For each one of the users I like to get the latest test score (month wise) for the year broken down by month with their score. In other words, I like to get the last score per user per month for a given year.
so for the above it would be
username date testscore
mike 2016-11-30 23:41:10.143 1
john 2016-11-28 23:41:11.143 7
mike 2016-10-30 23:41:10.143 1
john 2016-10-28 23:41:11.143 12
Perhaps using the WITH TIES clause in concert with Row_Number()
Select top 1 with ties *
from YourTable
Order by Row_Number() over (partition by UserName,year(date),month(date) order by date desc)
Returns
Username date testscore
john 2016-10-28 23:41:11.143 12
john 2016-11-28 23:41:11.143 7
mike 2016-10-30 23:41:10.143 1
mike 2016-11-30 23:41:10.143 1
You can use ROW_NUMBER():
WITH CTE AS
(
SELECT *,
RN = ROW_NUMBER() OVER(PARTITION BY username, CONVERT(VARCHAR(6),[date],112)
ORDER BY [date] DESC)
FROM dbo.YourTable
)
SELECT *
FROM CTE
WHERE RN = 1;
What about this :
select top 1 from <mytable> group by date.year(),date.month(),username order by date;
It seems you need a primary key, but you can still get the job done.
Essentially, you want the row for each username that corresponds to the latest date for that user.
SELECT username, date, testscore
FROM MyTable m1
WHERE m1.date = (SELECT MAX(m2.DATE))
FROM MyTable m2
WHERE m2.username = m1.username)
I have a table GAMES with this information:
Id_Game Id_Player1 Id_Player2 Week
--------------------------------------
1211 Peter John 2
1215 John Louis 13
1216 Louis Peter 17
I would like to get a list of the last week when each player has played, and the number of games, which should be this:
Id_Player Week numberGames
-----------------------------
Peter 17 2
John 13 2
Louis 17 2
But instead I get this one (notice on Peter week):
Id_Player Week numberGames
-----------------------------
Peter 2 2
John 13 2
Louis 17 2
What I do is this:
SELECT Id_Player,
MAX(Week) AS Week,
COUNT(*) as numberGames
FROM ((SELECT Id_Player1 as Id_Player, Week
FROM Games)
UNION ALL
(SELECT Id_Player2 as Id_Player, Week
FROM Games)) AS g2
GROUP BY Id_Player;
Could anyone help me to find the mistake?
What is the datatype of the Week column? If the datatype of Week is varchar you would get this behavior.