我试图在Vertica中使用Merge
命令仅从源表中插入不同的记录到目标表。我曾使用子查询在SQL
中尝试过同样的事情,但在vertica中它不允许。
以下是错误:
[Vertica][VJDBC](5665) ERROR: Subquery in MERGE is not supported
请帮助我。
提前致谢
答案 0 :(得分:1)
在vertica merge中无法使用Subquery。
MERGE INTO Target TGT
USING (Select distinct * from Sources) as SRC
ON TGT.CD = SRC.CD
我创建了一个视图:
Select distinct * from Sources
像这样使用它:
MERGE INTO Target TGT
USING SRC_VW as SRC
ON TGT.CD = SRC.CD
它解决了目的。只想将其张贴以供将来使用。
答案 1 :(得分:0)
您是否需要使用大数据量执行MERGE操作?
然后,您应该考虑启用优化的MERGE 计划而不是标准的MERGE,这要快得多。
如果您感兴趣,请大声说出来,我会在此向您解释详细信息。
快乐的玩耍
Marco the Sane
答案 2 :(得分:0)
优化MERGE可能性。
我将它基于残缺的慢速变化维度表。它带来了这个想法,但不要把它作为现实中任何事物的设计蓝图......!
假设您在目标表中拥有这些行。 cust_key是代理主键,cust_id和cust_to_dt的组合是表的另一个唯一标识符:
cust_key|cust_id|cust_to_dt|cust_first_name |cust_last_name |cust_phoneno |cust_loyalty_lvl|cust_org_id
1| 7|9999-12-31|Lionel |Prosser |+41(0)79 387 31 07| 1| 0
2| 14|9999-12-31|Hotblack |Desiato |+41(0)79 387 31 14| 2| 0
3| 21|9999-12-31|Slartibartfast |Slartibartfast |+41(0)79 387 31 21| 3| 0
4| 28|9999-12-31|Pizpot |Gargravarr |+41(0)79 387 31 28| 4| 0
5| 35|9999-12-31|Know-Nothing-Bozo|the Non-Wonder Dog|+41(0)79 387 31 35| 5| 0
6| 42|9999-12-31|Fook |Fook |+41(0)79 387 31 42| 6| 0
目标表的定义如下:
-- create a stand-alone sequence
CREATE SEQUENCE source_seq;
-- the target's surrogate key defaults to its sequence's NEXTVAL ….
CREATE TABLE target (
cust_key BIGINT DEFAULT target_seq.NEXTVAL NOT NULL
, cust_id BIGINT
, cust_to_dt DATE
, cust_first_name NCHAR VARYING(30)
, cust_last_name NCHAR VARYING(30)
, cust_phoneno NCHAR VARYING(30)
, cust_loyalty_lvl BIGINT
, cust_org_id BIGINT
, PRIMARY KEY(cust_key)
)
UNSEGMENTED ALL NODES;
您的源表 - 没有启动器的代理键值 - 看起来像这样。 6行是现有的更新行,1行是新行,Thor和cust_id 43。:
cust_id|cust_to_dt|cust_first_name |cust_last_name |cust_phoneno |cust_loyalty_lvl|cust_org_id
7|9999-12-31|Lionel |Prosser |+41(0)79 387 31 07| 2| 0
14|9999-12-31|Hotblack |Desiato |+41(0)79 387 31 14| 3| 0
21|9999-12-31|Slartibartfast |Slartibartfast |+41(0)79 387 31 21| 4| 0
28|9999-12-31|Pizpot |Gargravarr |+41(0)79 387 31 28| 5| 0
35|9999-12-31|Know-Nothing-Bozo|the Non-Wonder Dog|+41(0)79 387 31 35| 6| 0
42|9999-12-31|Fook |Fook |+41(0)79 387 31 42| 7| 0
43|9999-12-31|Thor |Thor |+41(0)79 623 84 75| 6| 1
您的MERGE源表的构建方式与目标表类似。:
CREATE TABLE merge_src LIKE target INCLUDING PROJECTIONS;
您可以从增量表中填充它,以便从目标中选择现有的代理键,并且在它们不存在的地方使用target_seq.NEXTVAL
来获取新的代理键。为此,您使用cust_id
和cust_to_dt
的组合将源加入目标,这是另一种唯一标识目标行的可能性:
INSERT /*+ DIRECT */ INTO merge_src
SELECT
IFNULL(tgt.cust_key,target_seq.NEXTVAL) AS cust_key
, src.cust_id
, src.cust_to_dt
, src.cust_first_name
, src.cust_last_name
, src.cust_phoneno
, src.cust_loyalty_lvl
, src.cust_org_id
FROM source src
LEFT
JOIN target tgt
USING(cust_id,cust_to_dt)
;
您的合并源表现在看起来像这样 - 带有cust_id 43的新行Thor,获取一个新的代理键:
SQL>select * from merge_src;
cust_key|cust_id|cust_to_dt|cust_first_name |cust_last_name |cust_phoneno |cust_loyalty_lvl|cust_org_id
1| 7|9999-12-31|Lionel |Prosser |+41(0)79 387 31 07| 2| 0
2| 14|9999-12-31|Hotblack |Desiato |+41(0)79 387 31 14| 3| 0
3| 21|9999-12-31|Slartibartfast |Slartibartfast |+41(0)79 387 31 21| 4| 0
4| 28|9999-12-31|Pizpot |Gargravarr |+41(0)79 387 31 28| 5| 0
5| 35|9999-12-31|Know-Nothing-Bozo|the Non-Wonder Dog|+41(0)79 387 31 35| 6| 0
6| 42|9999-12-31|Fook |Fook |+41(0)79 387 31 42| 7| 0
250,007| 43|9999-12-31|Thor |Thor |+41(0)79 623 84 75| 6| 1
merge_src和target之间的MERGE使用优化的MERGE,使用ON子句中的代理键(我刚用[...]占位符替换了GraphViz格式的有向图对象的代码)。特别注意DELETE的访问路径 - 它有一个MERGEJOIN(输入预先排序)并使用Side Information Passing(SIP1):
SQL>EXPLAIN
...>MERGE /*+DIRECT*/
...>INTO target t
...>USING merge_src s
...> ON s.cust_key = t.cust_key
...>WHEN MATCHED THEN UPDATE SET
...> cust_key = s.cust_key
...>, cust_id = s.cust_id
...>, cust_to_dt = s.cust_to_dt
...>, cust_first_name = s.cust_first_name
...>, cust_last_name = s.cust_last_name
...>, cust_phoneno = s.cust_phoneno
...>, cust_loyalty_lvl = s.cust_loyalty_lvl
...>, cust_org_id = s.cust_org_id
...>WHEN NOT MATCHED THEN INSERT (
...> cust_key
...>, cust_id
...>, cust_to_dt
...>, cust_first_name
...>, cust_last_name
...>, cust_phoneno
...>, cust_loyalty_lvl
...>, cust_org_id
...>) VALUES (
...> s.cust_key
...>, s.cust_id
...>, s.cust_to_dt
...>, s.cust_first_name
...>, s.cust_last_name
...>, s.cust_phoneno
...>, s.cust_loyalty_lvl
...>, s.cust_org_id
...>);
QUERY PLAN
------------------------------
QUERY PLAN DESCRIPTION:
------------------------------
EXPLAIN MERGE /*+DIRECT*/ INTO target t USING merge_src s ON s.cust_key = t.cust_key WHEN MATCHED THEN UPDATE SET cust_key = s.cust_key , cust_id = s.cust_id , cust_to_dt = s.cust_to_dt , cust_first_name = s.cust_first_name , cust_last_name = s.cust_last_name , cust_phoneno = s.cust_phoneno , cust_loyalty_lvl = s.cust_loyalty_lvl , cust_org_id = s.cust_org_id WHEN NOT MATCHED THEN INSERT ( cust_key , cust_id , cust_to_dt , cust_first_name , cust_last_name , cust_phoneno , cust_loyalty_lvl , cust_org_id ) VALUES ( s.cust_key , s.cust_id , s.cust_to_dt , s.cust_first_name , s.cust_last_name , s.cust_phoneno , s.cust_loyalty_lvl , s.cust_org_id )
Access Path:
+-DML INSERT [Cost: 0, Rows: 0]
| Target Projection: scd.target_super
| Target Prep:
| +---> STORAGE ACCESS for s [Cost: 40, Rows: 7 (NO STATISTICS)] (PATH ID: 3)
| | Projection: scd.merge_src_super
| | Materialize: s.cust_key, s.cust_id, s.cust_to_dt, s.cust_first_name, s.cust_last_name, s.cust_phoneno, s.cust_loyalty_lvl, s.cust_org_id
[...]
Lock Map - Table (Mode)
----------------------------------------------
target(I)
----------------------------------------------
------------------------------
QUERY PLAN DESCRIPTION:
------------------------------
EXPLAIN MERGE /*+DIRECT*/ INTO target t USING merge_src s ON s.cust_key = t.cust_key WHEN MATCHED THEN UPDATE SET cust_key = s.cust_key , cust_id = s.cust_id , cust_to_dt = s.cust_to_dt , cust_first_name = s.cust_first_name , cust_last_name = s.cust_last_name , cust_phoneno = s.cust_phoneno , cust_loyalty_lvl = s.cust_loyalty_lvl , cust_org_id = s.cust_org_id WHEN NOT MATCHED THEN INSERT ( cust_key , cust_id , cust_to_dt , cust_first_name , cust_last_name , cust_phoneno , cust_loyalty_lvl , cust_org_id ) VALUES ( s.cust_key , s.cust_id , s.cust_to_dt , s.cust_first_name , s.cust_last_name , s.cust_phoneno , s.cust_loyalty_lvl , s.cust_org_id )
Access Path:
+-DML DELETE [Cost: 0, Rows: 0]
| Target Projection: scd.target_super (DELETE ON CONTAINER)
| Target Prep:
| +---> JOIN MERGEJOIN(inputs presorted) [Semi] [Cost: 11, Rows: 7 (NO STATISTICS)] (PATH ID: 1)
| | Join Cond: (VAL(2) = t.cust_key)
| | +-- Outer -> STORAGE ACCESS for t [Cost: 5, Rows: 6 (NO STATISTICS)] (PATH ID: 2)
| | | Projection: scd.target_super
| | | Materialize: t.cust_key
| | | Runtime Filter: (SIP1(MergeJoin): t.cust_key)
| | +-- Inner -> SELECT [Cost: 5, Rows: 7 (NO STATISTICS)] (PATH ID: 3)
| | | +---> STORAGE ACCESS for s [Cost: 5, Rows: 7 (NO STATISTICS)] (PATH ID: 4)
| | | | Projection: scd.merge_src_super
| | | | Materialize: s.cust_key
Lock Map - Table (Mode)
----------------------------------------------
target(X)
----------------------------------------------
希望这一切都有道理......
快乐的比赛 -
Marco the Sane