如何加入 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 已于 1 月
移至 位置 A
- (2 月 住在那里)
- 并于 3 月
搬到了 位置 B
现在我想在每个 月查看 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
我正在使用 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 已于 1 月 移至 位置 A
- (2 月 住在那里)
- 并于 3 月 搬到了 位置 B
现在我想在每个 月查看 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