ПРИСОЕДИНЯЙТЕСЬ к 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);

Я пытаюсь получить конвертацию валют, основанную на датах (только месяц и год) в каждой из таблиц. Некоторые из конвертации валюты отличаются (оператор CASE для поля net_value_trans_currency_netwr). Я хочу, чтобы поле net_value_trans_currency_netwr было новой строкой, которая отображает конвертацию валюты в долларах США. Исходная таблица содержит более 5 миллионов строк. После соединений я получаю больше строк. Из того, что я собираю, я получаю полное соединение. Как я смогу выполнить то, что я пытаюсь сделать, без полного объединения, создающего больше, чем нужно строк?

2 ответа

Вы получаете повторяющиеся строки, поскольку вы ВНУТРЕННЕ СОЕДИНЯЕТЕСЬ на месяц и год, которые не являются уникальными. Это вызывает перекрестное соединение, например

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)

Если вы хотите избежать этого, вам нужно включить в объединение что-то еще, что сделает каждое объединение уникальным! Добавление дня может помочь, но опять же, если в один и тот же день записано более одной даты, вы получите дубликат. Подумайте, что еще вы можете включить в соединение.

Использование 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);

Кроме того, вы, вероятно, хотите ограничить присоединение дальше. Это ограниченное перекрестное соединение, в результате чего получается декартово произведение. Если у вас есть 3 строки на март 2014 года в tableA и 4 строки за март 2014 года в tableB, вы уже получите 12 строк в результате.

Другие вопросы по тегам