SQL: Comparing MAX Dates from Two different Tables - sql

I have 3 Tables
User
Attendence
Payment
Now I like to get
GroupID, UserName, MAX(PaymetDate), MAX(AttendenceDate)
Where MAX(PaymetDate) IS LESS THAN MAX(AttendenceDate)
This what I have Tried
SELECT MAX(PaymetDate) AS Paied_Upto
FROM Payment
Group by GroupID
SELECT MAX(AttendenceDate) AS Last_ AttendenceDate
FROM Attendence FULL OUTER JOIN Users ON Attendence.Username = Users.Username
Group by Users.GroupID
But how do get them to work together?
Thank

Try this:
SELECT u.GroupID, u.UserName, py.LastPaymentDate, at.LastAttendenceDate
FROM User AS u,
(SELECT Username, Max(AttendenceDate) AS LastAttendenceDate FROM Attendence GROUP BY Username) AS at,
(SELECT GroupID, Max(PaymetDate) AS LastPaymentDate FROM Payment GROUP BY GroupID) AS py
WHERE u.UserName=at.Username
AND u.GroupID=py.GroupID
AND py.LastPaymentDate < at.LastAttendenceDate;

try this
select p.GroupID, u.UserName, MAX(p.PaymetDate), MAX(a.AttendenceDate)
from dbo.Users u
inner join dbo.Attandence a
ON u.UserName = a.UserName
Inner join dbo.Payment p
ON u.groupID = p.GroupID
GROUP BY p.GroupID, u.UserName
Having MAX(p.PaymentDate) < MAX(a.attendenceDate)

I think this does what you need (SqlFiddle link):
select UserName, GroupID, MaxAttendanceDate, MaxPaymentDate
from (
select
u.UserName,
u.GroupID,
(select max(AttendanceDate)
from Attendance a
where a.UserName = u.UserName) as MaxAttendanceDate,
(select max(PaymentDate)
from Payment p
where p.GroupID = u.GroupId) as MaxPaymentDate
from [User] u
) x
where MaxAttendanceDate > MaxPaymentDate

Related

SQL SUM and COUNT from different tables

Tables:
UserReward:
UserRewardID PK
RewardID FK
UserID FK
UserBadge:
UserBadgeID PK
BadgeID FK
UserID FK
UserScore:
UserScoreID PK
UserID FK
LeaderboardID FK
I need to know the sum of score, the count of userbadge and the count of userReward.
I tried this but values are not right:
Select
u.username,
sum(us.score) as Soma_Score,
count(ur.userId) as Numero_de_rewards,
count(ub.userId) as Numero_de_crachas
from [user] u
join userscore us on u.userId = us.userID
join userbadge ub on ub.userid = u.userid
join userreward ur on ur.userid= u.userid
group by u.username
Have you looked at the rows before aggregating them? Your JOINs are duplicating many rows.
The best approach is to join the rows after aggregation:
with score(userid, score) as (
Select userid
, sum(us.score) as Soma_Score
from userscore us
group by userid
), rewards (userid, rewards) as (
select userid
, count(ur.userId) as Numero_de_rewards
from userreward ur
group by userid
), crachas (userid, crachas) as
select userid
, count(userId)
from userbadge
group by userid
)
select
u.userid
, score.score
, rewards.rewards
, crachas.crachas
from user u
left join score on u.userid=score.userid
left join rewards on u.userid=rewards.userid
left join crachas on u.userid=crachas.userid
Try:
SELECT
u.username,
(SELECT SUM(us.score) FROM userscore us WHERE us.userid = u.userid) as Soma_Score,
(SELECT COUNT(ur.userId) FROM userreward ur WHERE ur.userid = u.userid) as numero_de_rewards,
(SELECT COUNT(ub.userId) FROM userbadge ub WHERE ub.userid = u.userid) as numero_de_crachas
FROM [user] u

max(count(*)) Error: single-group group function

Assume I have two tables:
users
sells
I need to alter this query: Show top three users who bought copies of softwareMy SQL is this:
select u.name, u.age, u.sex, u.email, s.selluid, max(count(u.uid)) FROM users u, sells s where u.usrid = s.selluid
Any idea about how to solve this problem? Thanks
Try this
select u.usrid, u.name, count(s.sellid)
from users u left join sells s on u.usrid=s.selluid
group by u.usrid, u.name order by count(s.sellid) desc;
You can solve this using an aggregation subquery with row_number():
select u.*, s.numsales
from users u join
(select s.selluid, count(*) as numsales,
row_number() over (order by count(*) desc) as seqnum
from sells s
group by s.selluid
) s
on u.userid = s.selluid
where seqnum <= 3;
One advantage to this approach is that you can readily get all the columns from users using just u.*.
SELECT x.*
FROM (
SELECT u.name
, u.age
, u.sex
, u.email
, s.selluid
, COUNT(*) as t
FROM users u JOIN sells s ON u.usrid = s.selluid
GROUP BY u.name
ORDER BY COUNT(*) DESC
) x
WHERE ROWNUM <= 3

Challenge in PostgreSQL query (group by and having issue)

I'm trying to create a query but i'm having some trouble with it. I have two tables:
users (id, name, email)
comments (id, uid, comment, date, time)
I'm trying to list all users and their comments, which can be done quite easily with an inner join. However, i get various comments per user, since i joined the result. I just want their latest comment. Any ideas? :)
this should do it:
select distinct on(u.name, u.id) *
from comments c, users u
where u.id=c.uid
order by u.name, u.id, c.date desc
For PostgreSQL 8.4+:
SELECT x.*
FROM (SELECT u.*, c.*,
ROW_NUMBER() OVER (PARTITION BY u.id
ORDER BY c.date DESC, c.time DESC) AS rnk
FROM USERS u
JOIN COMMENTS c ON c.uid = u.id) x
WHERE x.rnk = 1
This might work:
EDIT:
I updated the query to this:
SELECT u.id, u.name, u.email, t.id, t.uid, t.comment, t.date, t.time
FROM users u
LEFT OUTER JOIN
(
select c.id, m.uid, c.comment, m.cdate, c.time
from comments c
right outer join
(
select uid, max(date) as cdate
from comments
group by uid
) as m
ON c.cdate = m.cdate
) t
ON u.id = t.uid
Assuming comment id is autoincrement, find the maximum commentid per user (the latest comment)
SELECT u.id, u.name, u.email, c.id, c.uid, c.comment, c.date, c.time
FROM users u
JOIN comments c ON u.id = c.uid
JOIN
(
select uid, max(id) id
from comments
group by uid
) as c2 ON c.id = c2.id AND c.uid = c2.uid
OMG Ponies certainly has the best answer, but here is another way to do it, without any extended database feature:
select
u.name,
c.comment,
c.comment_date_time
from users as u
left join comments as c
on c.uid = u.id
and
c.comment_date_time -
(
select max(c2.comment_date_time)
from comments as c2
where c2.uid = u.id
) = 0
I have merge your date and time columns into comment_date_time in this example.

postgresql database

i wanna to make a query that select users that have same username and same hour of creation date by using postgresql database
Something like this should do the trick. This will return any user/hour pair along with the count (untested):
select users.username, datepart('hour', users.created_at), count(*) from users
inner join users u2
on users.username = u2.username
and datepart('hour', users.created_at) = datepart('hour', u2.created_at)
group by users.username, datepart('hour', users.created_at) having count(*) > 1
select u.*
from users u
join (
select username, date_trunc('hour', creation_timestamp)
from users
group by 1, 2
having count(*) > 1
) as x on u.username = x.username
order by u.username;
Should work nicely.

How to select all users who made more than 10 submissions

I have a submission table that is very simple: userId, submissionGuid
I want to select the username (simple inner join to get it) of all the users who have more than 10 submissions in the table.
I would do this with embedded queries and a group by to count submissions... but is there a better way of doing it (without embedded queries)?
Thanks!
This is the simplest way, I believe:
select userId
from submission
group by userId
having count(submissionGuid) > 10
select userId, count(*)
from submissions
having count(*) > 10
group by userId
SELECT
username
FROM
usertable
JOIN submissions
ON usertable.userid = submissions.userid
GROUP BY
usertable.username
HAVING
Count(*) > 1
*Assuming that your "Users" table is call usertable and that it has a column called "UserName"
I think the correct query is this (SQL Server):
SELECT s.userId, u.userName
FROM submission s INNER JOIN users u on u.userId = s.userId
GROUP BY s.userId, u.username
HAVING COUNT(submissionGuid) > 10
If you don't have the HAVING clause:
SELECT u.userId, u.userName
FROM users u INNER JOIN (
SELECT userId, COUNT(submissionGuid) AS cnt
FROM submission
GROUP BY userId ) sc ON sc.userId = u.userId
WHERE sc.cnt > 10
select userid, count(submissionGUID) as submitCount
from Submissions
group by userid, submitCount
having submitCount > 10