如何加入 table 以获得类似于 Excel VLOOKUP-Range-Function 的值?

How can I join a table to get values similar to the Excel VLOOKUP-Range-Function?

我正在使用 HP Vertica 来编写我的查询。我想 select 一些看起来应该像 Excel 的数据,当你使用 VLOOKUP 函数并启用 范围标志 [ VLOOKUP( A1;B1:C4;2;1)].

我举一个简单的例子让你更好的理解。我有一个 table 显示历史仓库移动。

stock_history 
-------------

|product|location|time_stamp  |
|-------|--------|------------|
| A     | Loc A  | 2015-01-13 |
| A     | Loc B  | 2015-03-13 |

现在我想在每个 月查看 A 的位置(假设每月只允许移动一次以使其更容易)

它应该是这样的

|product|location|month    |
|-------|--------|----- ---|
| A     | Loc A  | 2015-01 |
| A     | Loc A  | 2015-02 |
| A     | Loc B  | 2015-03 |

我生成了一个显示所有月份的 table:

all_months
----------

|month    |
|---------| 
| 2015-01 |
| 2015-02 |
| 2015-03 |

这是我试过的声明

select his.product
     , his.location
     , mon.month

from stock_history as his

left outer join all_months as mon
on mon.month = to_char( time_stamp, 'YYYY-MM' )

|product |location|month    |
|--------|--------|----- ---|
| A      | Loc A  | 2015-01 |
| (null) | (null) | 2015-02 |
| A      | Loc B  | 2015-03 |

我如何设法让产品 A 也出现在 2 月线中,因为它在 2 月仍在位置 A?

感谢阅读我的问题。我期待着得到你的答案 ;)

此致, 菲利克斯

您可以使用 cross join 生成所有 month/product 组合。然后使用相关子查询从最近或当前月份获取位置:

select mon.month, p.product,
       (select sh.location
        from stock_history sh
        where mon.month <= to_char(sh.time_stamp, 'YYYY-MM' ) and p.product = sh.product
        order by mon.month desc
        limit 1
       ) as location
from (select distinct product p from stock_history) p cross join
     all_months mon;

给你! 我还添加了 months.Made 使用递归功能的示例。 我用 oracle 测试过,应该也适用于 vertica。

CREATE TABLE A 
(PRODUCT CHAR(1),LOCATION VARCHAR(10),MONTHS VARCHAR(10))

INSERT INTO A (PRODUCT,LOCATION,MONTHS)
SELECT 'A','LOC A','2015-01' FROM DUAL
UNION
SELECT 'A','LOC B','2015-03' FROM DUAL

CREATE TABLE MONTHS
(MON VARCHAR(10))

INSERT INTO MONTHS(MON)
SELECT '2015-01' FROM DUAL
UNION
SELECT '2015-02' FROM DUAL
UNION
SELECT '2015-03' FROM DUAL
UNION
SELECT '2015-04' FROM DUAL
UNION
SELECT '2015-05' FROM DUAL
UNION
SELECT '2015-06' FROM DUAL
COMMIT

WITH CTE (I,PRODUCT,LOCATION,MON) AS
(
SELECT 1 I,BASE.PRODUCT,A.LOCATION,M.MON
FROM 
(SELECT DISTINCT PRODUCT FROM A)BASE
CROSS JOIN 
MONTHS M
LEFT JOIN A
ON A.MONTHS=M.MON
UNION ALL
SELECT I+1,PRODUCT,COALESCE(LOCATION,LAG(LOCATION)OVER(PARTITION BY PRODUCT ORDER BY MON)) AS LOC,MON
FROM 
CTE WHERE I<12
)
SELECT DISTINCT PRODUCT,LOCATION,MON FROM CTE WHERE LOCATION IS NOT NULL
ORDER BY MON