ПРИСОЕДИНЯЙТЕСЬ к 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 строк в результате.