如果有,请按月加入,否则请按月加入

时间:2018-11-02 18:05:57

标签: sql amazon-redshift

我在这里有一个场景

表A:

---------------------------------------------
Req        CreatedMth     Amount      By
---------------------------------------------
R1         201806         100         John  
R2         201805         200         Mary  

表B:

-----------------------------------------------------
User         AvailableinOrgMonth            Position
-----------------------------------------------------
John         201805                         P1  
John         201806                         P1  
John         201807                         P1  
John         201808                         P1  
Mary         201803                         P1  
Mary         201804                         P1  

预期结果:

-----------------------------------------------------------------------------
Req    CreatedMth     Amount      By     AvailableinOrgMonth       Position
-----------------------------------------------------------------------------
R1     201806         100         John   201806                    P1  
R2     201805         200         Mary   201804                    P1  

这里的逻辑是,如果表B中有该月可用的用户,请加入该用户。否则,找到用户可用的最近月份,然后加入。 现在您可能会说,如果Mary在201805中不可用,她将如何创建请求。表B中的问题是每天替换当月的数据,并保留该月的最后一天的数据。因此,玛丽可能在2018-05-02创建了请求,但在2018-05-31离开了,因此她每月的数据不会出现在201806中。 我写了下面的查询

SELECT
  A.Req, 
  A.CreatedMth, 
  A.Amount, 
  A.By, 
  A.AvailableinOrgMonth, 
  A.Position 
FROM 
  Table A as A 
  LEFT JOIN (
    Select 
      *, 
      MAX(AvailableinOrgMonth) OVER (PARTITION BY user) as Maxmonth 
    FROM 
      Table B
  ) B ON A.By = B.User 
  AND (
    A.CreatedMth = B.AvailableinOrgMonth 
    OR (
      A.CreatedMth != B.AvailableinOrgMonth 
      AND B.AvailableinOrgMonth = B.Maxmonth
    )
  )

这将返回

Req    CreatedMth     Amount      By     AvailableinOrgMonth       Position
--------------------------------------------------------------------------------
R1     201806         100         John   201806                    P1  
R1     201806         100         John   201808                    P1(dup)  
R2     201805         100         Mary   201804                    P1  

如何获得正确的结果。 谢谢。

2 个答案:

答案 0 :(得分:2)

您需要在日期或该日期之前有效的要求。让我假设B每行都有唯一的标识符。然后,您可以使用相关子查询获取相应的行:

select a.*,
       (select b.b_id
        from b
        where b.user = a.by and b.AvailableinOrgMonth <= a.CreatedMth 
        limit 1
       ) as b_id
from a;

然后,您可以通过另一个join获取其他信息:

select a.*, b.*
from (select a.*,
             (select b.b_id
              from b
              where b.user = a.by and b.AvailableinOrgMonth <= a.CreatedMth 
              limit 1
             ) as b_id
      from a
     ) a left join
     b
     on a.b_id = b.b_id;

答案 1 :(得分:0)

我认为您正在寻找

SELECT T1.*,
       CASE WHEN EXISTS(
                        SELECT 1
                        FROM T2
                        WHERE T1.[By] = T2.[User]
                              AND
                              T1.CreatedMth = T2.AvailableinOrgMonth
                       )
           THEN T1.CreatedMth
           ELSE MAX(T2.AvailableinOrgMonth) 
           END AvailableinOrgMonth,
       T2.Position
FROM T1 INNER JOIN T2 ON T1.[By] = T2.[User]
GROUP BY
         T1.Req,
         T1.CreatedMth,
         T1.Amount,
         T1.[By],
         T2.Position;

返回:

+-----+------------+--------+------+---------------------+----------+
| Req | CreatedMth | Amount |  By  | AvailableinOrgMonth | Position |
+-----+------------+--------+------+---------------------+----------+
| R1  |     201806 |    100 | John |              201806 | P1       |
| R2  |     201805 |    200 | Mary |              201804 | P1       |
+-----+------------+--------+------+---------------------+----------+

但是,我不知道您从哪里获得两行的金额100