在SQL Server 2008中,我想在可能有重复的密钥上加入两个表,但匹配对于其他列的信息是唯一的。
对于简化的购买记录示例,
Table A:
UserId PayDate Amount
1 2015 100
1 2010 200
2 2014 150
Table B:
UserId OrderDate Count
1 2009 4
1 2014 2
2 2013 5
Desired Result:
UserId OrderDate PayDate Amount Count
1 2009 2010 200 4
1 2014 2015 100 2
2 2013 2014 150 5
它保证:
表A和表B的行数相同,两个表中的UserId
都是相同的数字组。
对于任何UserId
,PayDate
总是晚于OrderDate
具有相同UserId
的行与Date
的排序序列匹配。例如,表A中的第1行应与表B中的第2行匹配
我的想法是,在两个表格上,首先按Date
排序,然后添加另一个Id
列,然后加入此Id
列。但我没有授权在数据库中写任何东西。我该怎么做这个任务?
答案 0 :(得分:2)
Row_Number()
将成为你的朋友。它允许您为结果集添加虚拟序列。
运行此并研究输出:
SELECT UserID
, OrderDate
, "Count" As do_not_use_reserved_words_for_column_names
, Row_Number() OVER (PARTITION BY UserID ORDER BY OrderDate) As sequence
FROM table_b
PARTITION BY
确定计数器何时应“重置”,即在更改UserID
ORDER BY
,你已经猜到了 - 确定了序列的顺序!
全部拉出来:
; WITH payments AS (
SELECT UserID
, PayDate
, Amount
, Row_Number() OVER (PARTITION BY UserID ORDER BY PayDate) As sequence
FROM table_b
)
, orders AS (
SELECT UserID
, OrderDate
, "Count" As do_not_use_reserved_words_for_column_names
, Row_Number() OVER (PARTITION BY UserID ORDER BY OrderDate) As sequence
FROM table_b
)
SELECT orders.UserID
, orders.OrderDate
, orders.do_not_use_reserved_words_for_column_names
, payments.PayDate
, payments.Amount
FROM orders
LEFT
JOIN payments
ON payments.UserID = orders.UserID
AND payments.sequence = orders.sequence
P.S。我选择了外部加入,因为我认为并不总是会为每个订单付款。
答案 1 :(得分:0)
尝试:
;WITH t1
AS
(
SELECT UserId, PayDate, Amount,
ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY PayDate) AS RN
FROM TableA
),
t2
AS
(
SELECT UserId, OrderDate, [Count],
ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY OrderDate) AS RN
FROM TableB
)
SELECT t1.UserId, t2.OrderDate, t1.PayDate, t1.Amount, t2.[Count]
FROM t1
INNER JOIN t2
ON t1.UserId = t2.UserId AND t1.RN = t2.RN