在DATEPART月份和年份加入会导致额外的行

时间:2014-03-17 22:19:49

标签: sql postgresql join cartesian-product datepart

我有两个包含日期字段的表。这个日期字段是我想要实现的JOIN原因之一,但我只想在月份和年份加入,而不是一天。当我尝试这样做时,有关三倍的记录数。我猜我的查询有问题吗?或者这甚至可能吗?我使用的是Postgres

SELECT a.load_date , a.mandt, a.vbeln,a.posnr, a.matnr, b.tfed
FROM tableA a
JOIN tableB b
ON date_part('month'::text, a.erdat) = date_part('month'::text, b.gdatu)
AND date_part('year'::text, a.erdat) = date_part('year'::text, b.gdatu)

编辑这是我的完整代码

 SELECT a.mandt, a.vbeln, 
   a.erdat, a.erzet, a.ernam, a.angdt, a.audat, a.vbtyp, a.trvog, 
   a.auart, a.submi, a.lifsk, a.faksk, a.netwr, a.waerk, a.vkorg, a.vtweg, a.spart, 
   a.vkgrp, a.vkbur, a.knumv, a.vdatu, a.vprgr, a.kalsm, a.vsbed, a.fkara, a.awahr, 
   a.bstnk, a.bstdk, a.telf1, a.kunnr, a.stafo, a.stwae, a.aedat, a.kvgr1,a.kvgr2, 
   a.kvgr3, a.kokrs, a.kkber, a.knkli, a.sbgrp, a.ctlpc, a.cmwae, a.cmfre, a.cmngv, 
   a.amtbl, a.hityp_pr, a.abrvw, a.vgbel, a.objnr, a.bukrs_vf, a.taxk1,a.xblnr, 
   a.vgtyp, a.abhod, a.abhov, a.stceg_l, a.landtx, a.fmbdat, a.vsnmr_v, a.handle, 
   a.yybcawv1, a.yybcawv2, a.yybcawv3, a.yyawv1dat, a.yyawv2dat, a.yybcawvc, 
   a.kvgr5, a.augru, a.autlf, a.bname, a.bnddt, a.bsark, a.cmnup, a.fiscalper,              
   a.fiscalyr, a.gwldt, a.ihrez, a.intind, a.intsum, a.rplnr, a.taxk2, a.yybabt, 
   a.yybemail, a.yybfax, a.yybname, a.yybphone, a.yyexporter, a.yypaypal_id, 
   a.yysd_projid, a.zone, a.zuonr, a.zz_campaign_id, a.zzedate, a.zzrev_cat_01, 
   a.zzrev_cat_02, a.zzrev_cat_03, a.zzrev_cat_04, a.zzrev_cat_05, a.zzrev_cat_06, 
   a.zzrev_cat_07, a.zzrev_cat_08, a.zzsdate, a.mahdt,
   CASE
        WHEN b.fcurr::text = 'USD'::text THEN a.netwr
        WHEN b.fcurr::text = 'JPY'::text AND b.kurst::text = 'M'::text THEN a.netwr * b.ukurs / 10::numeric
        WHEN b.fcurr::text = 'KRW'::text AND b.kurst::text = 'M'::text THEN a.netwr * b.ukurs / 10::numeric
        WHEN b.kurst::text = 'M'::text THEN a.netwr * b.ukurs
        ELSE a.netwr
    END AS net_value_trans_currency_netwr
FROM src.sap_vbak a
JOIN src.sap_tcurr b  
ON a.waerk::text = b.fcurr::text 
AND date_part('MONTH'::text, a.erdat::timestamp with time zone) = date_part('MONTH'::text, b.gdatu::timestamp with time zone)
AND date_part('YEAR'::text, a.erdat::timestamp with time zone) = date_part('YEAR'::text, b.gdatu::timestamp with time zone);

我试图根据每个表中的日期(仅限月份和年份)进行货币转换。某些货币转换是不同的(net_value_trans_currency_netwr字段的CASE语句)。我希望net_value_trans_currency_netwr字段是一个显示美元货币转换的新行。原始表有超过500万行。在连接之后,我最终会有更多行。从我收集的内容来看,我得到了一个完整的加入。如果没有完全连接创建超过需要的行,我将如何执行我尝试做的事情?

2 个答案:

答案 0 :(得分:2)

您在月份和年份的INNER JOINING中获得重复的行,这些行不是唯一的。这导致交叉连接,例如

Example Rows with dates
   Date          Month    Year
1  01/01/2014    01       14
2  02/01/2014    01       14

Result of above join has 4 rows not 2!
1) Month from (1) Year from (1)
2) Month from (1) Year from (2)
3) Month from (2) Year from (1)
4) Month from (2) Year from (2)

如果您想避免这种情况,您需要在联接中包含其他内容,以使每个联接都是唯一的!添加日期可能会有所帮助,但如果您在同一天录制了多个日期,则会获得重复日期。想一想你可以在加入中包含什么。

答案 1 :(得分:0)

使用date_trunc()简化查询:

SELECT a.load_date, a.mandt, a.vbeln,a.posnr, a.matnr, b.tfed
FROM   tableA a
JOIN   tableB b ON date_trunc('month', a.erdat)
                 = date_trunc('month', b.gdatu);

另外,您可能希望进一步限制联接。这是一个有限的交叉加入,产生Cartesian product。如果2014年3月的tableA中有3行,tableB中有2014年3月的4行,则结果中已生成12行。