2

我有两个包含日期字段的表。这个日期字段是我想要实现的 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 万行。加入后,我得到了更多的行。从我收集到的信息来看,我得到了一个完整的加入。如果没有完全连接创建超过需要的行,我将如何执行我正在尝试做的事情?

4

2 回答 2

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)

如果您想避免这种情况,您需要在连接中包含其他内容,以使每个连接都独一无二!添加日期可能会有所帮助,但如果您在同一天记录了多个日期,您将再次获得重复。想想你还可以在加入中包含什么。

于 2014-03-17T22:28:16.277 回答
1

用于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);

另外,您可能希望进一步限制加入。这是导致笛卡尔积的有限交叉连接。如果 a 中有 2014 年 3 月的 3 行,a 中有 2014 年 3 月的4 行,则您已经在结果中生成了 12 行。tableAtableB

于 2014-03-17T22:56:25.113 回答