将 2 table 与每行之间的日期映射

Mapping 2 table with between date for each row

我有 2 个 table 列,如下所示:

Table一个

rows, key_a, date_a
   1,  'k1', '2015-11-12'
   2,  'k2', '2015-11-20'
   3,  'k3', '2015-12-01'

TableB

row, key_b, date_b,     Code
 1,  'k1', '2015-10-12', C1
 2,  'k1', '2015-09-12', C2
 3,  'k1', '2015-11-01', C3
 4,  'k1', '2015-10-20', C4
 5,  'k1', '2015-08-19', C5
 6,  'k1', '2015-11-02', C6
 7,  'k2', '2015-10-12', C7
 8,  'k2', '2015-09-12', C8
 9,  'k2', '2015-11-01', C9
 10,  'k2', '2015-10-20', C10
 11,  'k2', '2015-08-19', C11
 12,  'k2', '2015-11-02', C12
 13,  'k3', '2015-10-12', C13
 14,  'k3', '2015-09-12', C14
 15,  'k3', '2015-11-01', C15
 16,  'k3', '2015-10-20', C16
 17,  'k3', '2015-08-19', C17
 18,  'k3', '2015-11-02', C18

我想在 table B 中找到行 date_b 是第一个具有相同 key_b 并且只有 select 数据在 table B 中具有 date_bdate_adate_a - 30

意思是:

 'k1' => '2015-11-12' to '2015-10-12' => rows view (1,3,4,6)
 'k2' => '2015-11-20' to '2015-10-20' => rows view (9,10,12)
 'k3' => '2015-12-01' to '2015-11-01' => rows view (15,18)

结果

key_a, date_a,       Code
 'k1', '2015-11-12', C1
 'k2', '2015-11-20', C10
 'k3', '2015-12-01', C15

我该怎么做?

所以这是你可能想要的:

select key_a,first(date_a) as first_date_a,group_concat(code) as all_codes,first(code) as first_code from (
select * from (select 1 as rows,  'k1' as key_a, date('2015-11-12') as date_a),
(select 2 as rows,  'k2' as key_a, date('2015-11-20') as date_a),
(select 3 as rows,  'k3' as key_a, date('2015-12-01') as date_a)
) table_a
join (select * from
 (select 1 as rows,  'k1' as key_b, date('2015-10-12') as date_b, 'C1' as code),
 (select 2 as rows,  'k1' as key_b, date('2015-09-12') as date_b, 'C2' as code),
 (select 3 as rows,  'k1' as key_b, date('2015-11-01') as date_b, 'C3' as code),
 (select 4 as rows,  'k1' as key_b, date('2015-10-20') as date_b, 'C4' as code),
 (select 5 as rows,  'k1' as key_b, date('2015-08-19') as date_b, 'C5' as code),
 (select 6 as rows,  'k1' as key_b, date('2015-11-02') as date_b, 'C6' as code),
 (select 7 as rows,  'k2' as key_b, date('2015-10-12') as date_b, 'C7' as code),
 (select 8 as rows,  'k2' as key_b, date('2015-09-12') as date_b, 'C8' as code),
 (select 9 as rows,  'k2' as key_b, date('2015-11-01') as date_b, 'C9' as code),
 (select 10 as rows,  'k2' as key_b, date('2015-10-20') as date_b, 'C10' as code),
 (select 11 as rows,  'k2' as key_b, date('2015-08-19') as date_b, 'C11' as code),
 (select 12 as rows,  'k2' as key_b, date('2015-11-02') as date_b, 'C12' as code),
 (select 13 as rows,  'k3' as key_b, date('2015-10-12') as date_b, 'C13' as code),
 (select 14 as rows,  'k3' as key_b, date('2015-09-12') as date_b, 'C14' as code),
 (select 15 as rows,  'k3' as key_b, date('2015-11-01') as date_b, 'C15' as code),
 (select 16 as rows,  'k3' as key_b, date('2015-10-20') as date_b, 'C16' as code),
 (select 17 as rows,  'k3' as key_b, date('2015-08-19') as date_b, 'C17' as code),
 (select 18 as rows,  'k3' as key_b, date('2015-11-02') as date_b, 'C18' as code)
 ) table_b
 on table_a.key_a=table_b.key_b
 where timestamp(date_b) between DATE_ADD(timestamp(date_a), -1, "MONTH") and timestamp(date_a)
 group by 1

returns:

+-----+-------+--------------+-------------+------------+---+
| Row | key_a | first_date_a |  all_codes  | first_code |   |
+-----+-------+--------------+-------------+------------+---+
|   1 | k1    | 2015-11-12   | C1,C3,C4,C6 | C1         |   |
|   2 | k2    | 2015-11-20   | C9,C10,C12  | C9         |   |
|   3 | k3    | 2015-12-01   | C15,C18     | C15        |   |
+-----+-------+--------------+-------------+------------+---+
SELECT key_a, date_a, code
FROM (
  SELECT *, ROW_NUMBER() OVER(PARTITION BY key_a ORDER BY date_b) AS num
  FROM (
    SELECT  key_a, date_a, date_b, code,
    FROM    table_a AS a 
    JOIN    table_b AS b
    ON      a.key_a = b.key_b
    WHERE date_b BETWEEN DATE(DATE_ADD(TIMESTAMP(date_a), -1, "MONTH")) AND date_a 
  )
)
WHERE num = 1
ORDER BY key_a

结果:

key_a   date_a      code
k1      2015-11-12  C1
k2      2015-11-20  C10
k3      2015-12-01  C15

这绝对是一个 hacky 方法,但这应该可行

Select key_a, first(date_a), RIGHT(first(amalgam),3) from( select key_a, date_a, date_b + ' ' + code as amalgam from (
select * from (select 1 as rows,  'k1' as key_a, date('2015-11-12') as date_a),
(select 2 as rows,  'k2' as key_a, date('2015-11-20') as date_a),
(select 3 as rows,  'k3' as key_a, date('2015-12-01') as date_a)
) table_a
join (select * from
(select 1 as rows,  'k1' as key_b, date('2015-10-12') as date_b, 'C1' as code),
(select 2 as rows,  'k1' as key_b, date('2015-09-12') as date_b, 'C2' as code),
(select 3 as rows,  'k1' as key_b, date('2015-11-01') as date_b, 'C3' as code),
(select 4 as rows,  'k1' as key_b, date('2015-10-20') as date_b, 'C4' as code),
(select 5 as rows,  'k1' as key_b, date('2015-08-19') as date_b, 'C5' as code),
(select 6 as rows,  'k1' as key_b, date('2015-11-02') as date_b, 'C6' as code),
(select 7 as rows,  'k2' as key_b, date('2015-10-12') as date_b, 'C7' as code),
(select 8 as rows,  'k2' as key_b, date('2015-09-12') as date_b, 'C8' as code),
(select 9 as rows,  'k2' as key_b, date('2015-11-01') as date_b, 'C9' as code),
(select 10 as rows,  'k2' as key_b, date('2015-10-20') as date_b, 'C10' as code),
(select 11 as rows,  'k2' as key_b, date('2015-08-19') as date_b, 'C11' as code),
(select 12 as rows,  'k2' as key_b, date('2015-11-02') as date_b, 'C12' as code),
(select 13 as rows,  'k3' as key_b, date('2015-10-12') as date_b, 'C13' as code),
(select 14 as rows,  'k3' as key_b, date('2015-09-12') as date_b, 'C14' as code),
(select 15 as rows,  'k3' as key_b, date('2015-11-01') as date_b, 'C15' as code),
(select 16 as rows,  'k3' as key_b, date('2015-10-20') as date_b, 'C16' as code),
(select 17 as rows,  'k3' as key_b, date('2015-08-19') as date_b, 'C17' as code),
(select 18 as rows,  'k3' as key_b, date('2015-11-02') as date_b, 'C18' as code)
) table_b
on table_a.key_a=table_b.key_b
where timestamp(date_b) between DATE_ADD(timestamp(date_a), -1, "MONTH") and timestamp(date_a)) 
group by 1

如果你想要一个更简洁的解决方案,而不是在 date_b 和代码之间添加一个空格,你总是可以在不添加 space 的情况下添加它们,然后执行 RIGHT(2) 而不是 RIGHT (3)、取决于'amalgam'的长度。老实说,我更喜欢 Mikhail 的解决方案 :)