我在MS SQL Server中有两个表
一个包含有关用户的信息
TBL_USER
UserID| Name | Mail |...many columns...|
------+--------------+---------- +------------------+
292 | John Smith | @@@@@@@@ | ... |
293 | Anna Bennet | @@@@@@@@ | ... |
294 | Mark Johnson | @@@@@@@@ | ... |
其他表格是每个用户付款的注册表,其中UserID作为我的TBL_USER表格的外键
TBL_PAYMENT
UserID| PaymentID | Amount | PaymentDate |
------+-----------+----------------------+
292 | 782 | 378 | 02-17-2016 |
293 | 783 | 172 | 03-22-2016 |
292 | 784 | 395 | 03-28-2016 |
292 | 785 | 358 | 04-01-2016 |
293 | 786 | 826 | 05-07-2016 |
293 | 787 | 835 | 05-23-2016 |
我想要做的是一个查询语句或存储过程,当该用户没有像这样付款时,为每个用户和同一结果表中的最新付款带来一个表或null或任何其他静态值
UserID| Name | PaymentID | Amount | PaymentDate |
------+--------------+---------- +--------+-------------+
292 | John Smith | 785 | 358 | 04-01-2016 |
293 | Anna Bennet | 786 | 786 | 05-07-2016 |
294 | Mark Johnson | NULL | NULL | NULL |
现在我有以下声明,但这只给了我每个用户的最后一笔付款,只有他们完成了一次付款。我想在同一张表中找到遗失的报告。
SELECT
usr.UserID,
usr.UserName,
pay.PaymentID,
pay.Amount,
pay.PaymentDate
FROM TBL_USER usr
LEFT OUTER JOIN TBL_PAYMENT pay ON usr.UserID = pay.UserID
INNER JOIN (
SELECT UserID,MAX(PaymentDate) AS MAXDATE
FROM TBL_PAYMENT Group by UserID
) latest ON pay.UserID = latest.UserID AND pay.PaymentDate = latest.MAXDATE
任何人都可以帮我解决这个问题吗?
答案 0 :(得分:1)
使用窗口功能:
SELECT usr.UserID, usr.UserName,
pay.PaymentID, pay.Amount, pay.PaymentDate
FROM TBL_USER usr LEFT OUTER JOIN
(SELECT pay.*,
ROW_NUMBER() OVER (PARTITION BY userId Order by PaymentDate DESC) as seqnum
FROM TBL_PAYMENT pay
) pay
ON usr.UserID = pay.UserID AND seqnum = 1;
答案 1 :(得分:0)
如果每个用户不重复PaymentDates,这应该可以正常工作
SELECT
TBL_USER.UserId, TBL_USER.Name, pm.PaymentId, pm.Amount, pm.PaymentDate
FROM TBL_USER
LEFT JOIN (
SELECT
U.USERID,.MAX(P.PaymentDate) AS MAXDATE
FROM TBL_USER U
INNER JOIN TBL_PAYMENT P on U.UserID = P.UserID
group by U.USERID
) J
on TBL_USER.UserID = J.UserID
LEFT JOIN TBL_PAYMENT Pm on Pm.PaymentDate = J.MAXDATE
答案 2 :(得分:0)
WITH子句更具可读性 - 并且包含测试数据:
WITH
-- input, don't use in real query
tbl_user(UserID,Name,Mail) AS (
SELECT 292,'John Smith','@@@@@@@@'
UNION ALL SELECT 293,'Anna Bennet','@@@@@@@@'
UNION ALL SELECT 294,'Mark Johnson','@@@@@@@@'
)
,
tbl_payment(UserID,PaymentID,Amount,PaymentDate) AS (
SELECT 292,782,378,DATE '2016-02-17'
UNION ALL SELECT 293,783,172,DATE '2016-03-22'
UNION ALL SELECT 292,784,395,DATE '2016-03-28'
UNION ALL SELECT 292,785,358,DATE '2016-04-01'
UNION ALL SELECT 293,786,826,DATE '2016-05-07'
UNION ALL SELECT 293,787,835,DATE '2016-05-23'
)
-- end of input - start real query with WITH,
-- not comma, here
,
interesting_payments AS (
SELECT
u.userid
, MAX(paymentdate) AS paymentdate
FROM tbl_user u
LEFT JOIN tbl_payment USING(userid)
GROUP BY u.userid
)
SELECT
u.userid
, u.name
, p.paymentid
, p.amount
, p.paymentdate
FROM interesting_payments i
JOIN tbl_user u USING(userid)
LEFT JOIN tbl_payment p USING(userid,paymentdate)
;
userid|name |paymentid|amount|paymentdate
292|John Smith | 785| 358|2016-04-01
293|Anna Bennet | 787| 835|2016-05-23
294|Mark Johnson|NULL |NULL |NULL