diff --git a/apply_guidance.ts b/apply_guidance.ts index 90bb76b..732d127 100644 --- a/apply_guidance.ts +++ b/apply_guidance.ts @@ -16,135 +16,135 @@ export function apply_guidance(doc: any) { let mostRelevantCustomerSource = null; // Function to update price and assign relevance indicator - function setAnchors(items, channelFirstChar, v1ds, v0ds, histKey) { - for (let item of items) { - // Update the last_price with the most recent price - const years = Object.keys(item.season).map(Number).filter(year => year >= 2020); - if (years.length > 0) { - const recentYear = Math.max(...years.map(Number)); - const earlyYear = Math.min(...years.map(Number)); - const lastPrice = item.season[recentYear].price_usd; - const earlyPrice = item.season[earlyYear].price_usd; - item.last_price = lastPrice; - item.early_price = earlyPrice; - item.last_season = recentYear; - item.early_season = earlyYear; - } else { - item.last_price = null; // or some default value as appropriate - } + //function setAnchors(items, channelFirstChar, v1ds, v0ds, histKey) { + // for (let item of items) { + // // Update the last_price with the most recent price + // const years = Object.keys(item.season).map(Number).filter(year => year >= 2020); + // if (years.length > 0) { + // const recentYear = Math.max(...years.map(Number)); + // const earlyYear = Math.min(...years.map(Number)); + // const lastPrice = item.season[recentYear].price_usd; + // const earlyPrice = item.season[earlyYear].price_usd; + // item.last_price = lastPrice; + // item.early_price = earlyPrice; + // item.last_season = recentYear; + // item.early_season = earlyYear; + // } else { + // item.last_price = null; // or some default value as appropriate + // } - // Initialize relevance as numeric value - let marketRelevance = 0; // Assume 0 is 'not relevant' - let customerRelevance = 0; // Assume 0 is 'not relevant' + // // Initialize relevance as numeric value + // let marketRelevance = 0; // Assume 0 is 'not relevant' + // let customerRelevance = 0; // Assume 0 is 'not relevant' - // Check if the first character of the item's channel matches the first character of the document's channel - if (item.chan.charAt(0) === channelFirstChar) { - marketRelevance = 1; // 'relevant' + // // Check if the first character of the item's channel matches the first character of the document's channel + // if (item.chan.charAt(0) === channelFirstChar) { + // marketRelevance = 1; // 'relevant' - // Further refine relevance based on v1ds and v0ds - if (item.v1ds === v1ds) { - marketRelevance = 2; // 'most relevant' because v1ds matches + // // Further refine relevance based on v1ds and v0ds + // if (item.v1ds === v1ds) { + // marketRelevance = 2; // 'most relevant' because v1ds matches - // Check for customer relevance if 'cust' key exists - customerRelevance = item.cust ? 3 : 0; - } else if (item.v0ds === v0ds) { - marketRelevance = marketRelevance === 2 ? 2 : 1; // Keep relevance as is if v1ds was matched, otherwise it's just 'relevant' - customerRelevance = item.cust ? 2 : 0; - } else if (item.cust) { - customerRelevance = item.v1ds ? 2 : item.v0ds ? 1 : 0; - } - } + // // Check for customer relevance if 'cust' key exists + // customerRelevance = item.cust ? 3 : 0; + // } else if (item.v0ds === v0ds) { + // marketRelevance = marketRelevance === 2 ? 2 : 1; // Keep relevance as is if v1ds was matched, otherwise it's just 'relevant' + // customerRelevance = item.cust ? 2 : 0; + // } else if (item.cust) { + // customerRelevance = item.v1ds ? 2 : item.v0ds ? 1 : 0; + // } + // } - // Assign the calculated relevance to the item - item.marketRelevance = marketRelevance; - item.customerRelevance = customerRelevance; + // // Assign the calculated relevance to the item + // item.marketRelevance = marketRelevance; + // item.customerRelevance = customerRelevance; - // Update the most relevant market price if this item's relevance is higher and it doesn't have a 'cust' key - if (marketRelevance > highestMarketRelevanceLevel) { - highestMarketRelevanceLevel = marketRelevance; - mostRelevantMarketPrice = item.last_price; - mostRelevantMarketPriceEarly = item.early_price; - mostRelevantMarketKey = histKey; - mostRelevantMarketSource = item; - delete mostRelevantMarketSource.season; - mostRelevantMarketSeason = item.last_season; // Assuming 'season' is the key where the season info is stored - mostRelevantMarketSeasonEarly = item.early_season; - } + // // Update the most relevant market price if this item's relevance is higher and it doesn't have a 'cust' key + // if (marketRelevance > highestMarketRelevanceLevel) { + // highestMarketRelevanceLevel = marketRelevance; + // mostRelevantMarketPrice = item.last_price; + // mostRelevantMarketPriceEarly = item.early_price; + // mostRelevantMarketKey = histKey; + // mostRelevantMarketSource = item; + // delete mostRelevantMarketSource.season; + // mostRelevantMarketSeason = item.last_season; // Assuming 'season' is the key where the season info is stored + // mostRelevantMarketSeasonEarly = item.early_season; + // } - // Update the most relevant customer price if this item's relevance is higher and it has a 'cust' key - if (customerRelevance > highestCustomerRelevanceLevel) { - highestCustomerRelevanceLevel = customerRelevance; - mostRelevantCustomerPriceRecent = item.last_price; - mostRelevantCustomerPriceEarly = item.early_price; - mostRelevantCustomerKey = histKey; - mostRelevantCustomerSource = item; - delete mostRelevantCustomerSource.season; - mostRelevantCustomerSeasonRecent = item.last_season; // Assuming 'season' is the key where the season info is stored - mostRelevantCustomerSeasonEarly = item.early_season; // Assuming 'season' is the key where the season info is stored - } - } - } + // // Update the most relevant customer price if this item's relevance is higher and it has a 'cust' key + // if (customerRelevance > highestCustomerRelevanceLevel) { + // highestCustomerRelevanceLevel = customerRelevance; + // mostRelevantCustomerPriceRecent = item.last_price; + // mostRelevantCustomerPriceEarly = item.early_price; + // mostRelevantCustomerKey = histKey; + // mostRelevantCustomerSource = item; + // delete mostRelevantCustomerSource.season; + // mostRelevantCustomerSeasonRecent = item.last_season; // Assuming 'season' is the key where the season info is stored + // mostRelevantCustomerSeasonEarly = item.early_season; // Assuming 'season' is the key where the season info is stored + // } + // } + //} - // Iterate over each key in the "hist" object - for (let key of Object.keys(doc.hist)) { - // Update price and relevance for each item in the current key - setAnchors(doc.hist[key], doc.chan[0], doc.v1ds, doc.v0ds, key); - } + //// Iterate over each key in the "hist" object + //for (let key of Object.keys(doc.hist)) { + // // Update price and relevance for each item in the current key + // setAnchors(doc.hist[key], doc.chan[0], doc.v1ds, doc.v0ds, key); + //} - // Assign the most relevant market price and key to the top level of the document - if (mostRelevantMarketPrice !== null) { - doc.mostRelevantMarketPriceInfo = { - price: mostRelevantMarketPrice, - price_early: mostRelevantMarketPriceEarly, - source: mostRelevantMarketSource, - season: mostRelevantMarketSeason, - season_early: mostRelevantMarketSeasonEarly, - relevance: highestMarketRelevanceLevel - }; - } + //// Assign the most relevant market price and key to the top level of the document + //if (mostRelevantMarketPrice !== null) { + // doc.mostRelevantMarketPriceInfo = { + // price: mostRelevantMarketPrice, + // price_early: mostRelevantMarketPriceEarly, + // source: mostRelevantMarketSource, + // season: mostRelevantMarketSeason, + // season_early: mostRelevantMarketSeasonEarly, + // relevance: highestMarketRelevanceLevel + // }; + //} - // Assign the most relevant customer price and key to the top level of the document - if (mostRelevantCustomerPriceRecent !== null) { - doc.mostRelevantCustomerPriceInfo = { - price: mostRelevantCustomerPriceRecent, - price_early: mostRelevantCustomerPriceEarly, - source: mostRelevantCustomerSource, - season: mostRelevantCustomerSeasonRecent, - season_early: mostRelevantCustomerSeasonEarly, - relevance: highestCustomerRelevanceLevel - }; - } + //// Assign the most relevant customer price and key to the top level of the document + //if (mostRelevantCustomerPriceRecent !== null) { + // doc.mostRelevantCustomerPriceInfo = { + // price: mostRelevantCustomerPriceRecent, + // price_early: mostRelevantCustomerPriceEarly, + // source: mostRelevantCustomerSource, + // season: mostRelevantCustomerSeasonRecent, + // season_early: mostRelevantCustomerSeasonEarly, + // relevance: highestCustomerRelevanceLevel + // }; + //} - doc.targetPrice = doc.v1tp ?? doc.v0tp ?? null; - // Determine the anchor price and source - if (doc.targetPrice !== undefined && (mostRelevantCustomerPriceEarly === undefined || doc.targetPrice < mostRelevantCustomerPriceEarly)) { - doc.anchorPrice = doc.targetPrice; - doc.anchorSource = 'Target Price'; - } else if (mostRelevantCustomerPriceEarly !== undefined) { - doc.anchorPrice = mostRelevantCustomerPriceEarly; - doc.anchorSource = mostRelevantCustomerSeasonEarly + ' Customer Price'; - } else { - doc.anchorPrice = null; - doc.anchorSource = 'none'; // or any other default value you wish to indicate no anchor price was found - } + //doc.targetPrice = doc.v1tp ?? doc.v0tp ?? null; + //// Determine the anchor price and source + //if (doc.targetPrice !== undefined && (mostRelevantCustomerPriceEarly === undefined || doc.targetPrice < mostRelevantCustomerPriceEarly)) { + // doc.anchorPrice = doc.targetPrice; + // doc.anchorSource = 'Target Price'; + //} else if (mostRelevantCustomerPriceEarly !== undefined) { + // doc.anchorPrice = mostRelevantCustomerPriceEarly; + // doc.anchorSource = mostRelevantCustomerSeasonEarly + ' Customer Price'; + //} else { + // doc.anchorPrice = null; + // doc.anchorSource = 'none'; // or any other default value you wish to indicate no anchor price was found + //} - const inflation = Math.max(...Object.keys(doc.iidx).map(Number)); - const inflationFactor = doc.iidx[inflation] + 1; - doc.inflationFactor = inflationFactor; - var calcPrice = doc.anchorPrice * doc.inflationFactor; - calcPrice = parseFloat(calcPrice.toFixed(5)); - let finalReason = ""; - if (calcPrice >= doc.list) { - doc.calcCeiling = "Cap At List"; - doc.finalPrice = doc.list; - finalReason = `${doc.anchorSource} ${doc.anchorPrice} x ${inflationFactor} = ${calcPrice} but cap at list ${doc.list}`; - } else { - doc.finalPrice = calcPrice; - finalReason = `${doc.anchorSource} ${doc.anchorPrice} x ${inflationFactor} = ${calcPrice}`; - } - doc.finalReason = finalReason; + //const inflation = Math.max(...Object.keys(doc.iidx).map(Number)); + //const inflationFactor = doc.iidx[inflation] + 1; + //doc.inflationFactor = inflationFactor; + //var calcPrice = doc.anchorPrice * doc.inflationFactor; + //calcPrice = parseFloat(calcPrice.toFixed(5)); + //let finalReason = ""; + //if (calcPrice >= doc.list) { + // doc.calcCeiling = "Cap At List"; + // doc.finalPrice = doc.list; + // finalReason = `${doc.anchorSource} ${doc.anchorPrice} x ${inflationFactor} = ${calcPrice} but cap at list ${doc.list}`; + //} else { + // doc.finalPrice = calcPrice; + // finalReason = `${doc.anchorSource} ${doc.anchorPrice} x ${inflationFactor} = ${calcPrice}`; + //} + //doc.finalReason = finalReason; return doc; } diff --git a/sql/get_guidance.pg.sql b/sql/get_guidance.pg.sql index 6d2558d..e472ed9 100644 --- a/sql/get_guidance.pg.sql +++ b/sql/get_guidance.pg.sql @@ -62,7 +62,7 @@ BEGIN --RAISE NOTICE 'cust %', _cust; ----------------price history------------------------------- - SELECT _rslt||jsonb_build_object('hist',rlarp.gethist(_mold, _cust)) INTO _rslt ; + SELECT _rslt||jsonb_build_object('hist',rlarp.get_hist(_mold, _v1ds, _cust, substring(_chan,1,1))) INTO _rslt ; --RAISE NOTICE '%', _rslt; ----------------target pricing------------------------------ @@ -127,12 +127,12 @@ BEGIN priority; _rslt := _rslt||COALESCE(_iidx,'{}'::jsonb); - ----------------list ppricing------------------------------- + ----------------list pricing-------------------------------- SELECT coalesce(rlarp.get_list(_bill, _ship, _item, _qty),'{}'::jsonb) INTO _list; _rslt := _rslt||_list; --RAISE NOTICE 'list: %', jsonb_pretty(_list); - ----------------list ppricing------------------------------- + ----------------get premium for quote hist gap-------------- SELECT coalesce(rlarp.get_premium(_stlc, _seas, (SELECT xchan FROM _chx WHERE chan = _chan),_v1ds, ((_rslt->'mostRelevantCustomerPriceInfo')->'source')->>'v1ds'),'{}'::jsonb) INTO _prem; _rslt := _rslt||_prem; --RAISE NOTICE 'list: %', jsonb_pretty(_list); diff --git a/sql/get_guidance_dseg.pg.sql b/sql/get_guidance_dseg.pg.sql index 7f13723..dae4f74 100644 --- a/sql/get_guidance_dseg.pg.sql +++ b/sql/get_guidance_dseg.pg.sql @@ -62,23 +62,23 @@ BEGIN ,i.v0ds ,jsonb_strip_nulls(jsonb_build_object('assc',CASE WHEN i.assc <> '' THEN i.assc ELSE null::text END,'majg',i.majg::int,'coltier',i.coltier)); _rslt := jsonb_build_object('mold',_mold,'v1ds',_v1ds,'v0ds',_v0ds,'stlc',_stlc)||_iidx; - --RAISE NOTICE 'item data %', _iidx; + RAISE NOTICE 'item data %', _iidx; ----------------channel------------------------------------- SELECT rlarp.channel_code(_bill, _ship) INTO _chan; _rslt := _rslt||jsonb_build_object('chan',_chan); - --RAISE NOTICE '%', _chan; + RAISE NOTICE 'chan %', _chan; ----------------customer------------------------------------ SELECT dba INTO _cust FROM rlarp.cust WHERE code = CASE WHEN _chan = 'DRP' THEN _ship ELSE _bill END ; _rslt = _rslt||jsonb_build_object('cust',_cust); - --RAISE NOTICE 'cust %', _cust; + RAISE NOTICE 'cust %', _cust; ----------------price history------------------------------- - SELECT _rslt||jsonb_build_object('hist',rlarp.gethist(_mold, _cust)) INTO _rslt ; - --RAISE NOTICE '%', _rslt; + SELECT _rslt||jsonb_build_object('hist',rlarp.get_hist(_mold, _v1ds, _cust, substring(_chan,1,1))) INTO _rslt ; + RAISE NOTICE 'result %', _rslt; ----------------target pricing------------------------------ SELECT @@ -141,11 +141,17 @@ BEGIN GROUP BY priority; _rslt := _rslt||COALESCE(_iidx,'{}'::jsonb); - ----------------list ppricing------------------------------- + + ----------------list pricing--------------------------------- SELECT coalesce(rlarp.get_list(_bill, _ship, _item, _qty),'{}'::jsonb) INTO _list; _rslt := _rslt||_list; --RAISE NOTICE 'list: %', jsonb_pretty(_list); + ----------------get premium for quote hist gap-------------- + --SELECT coalesce(rlarp.get_premium(_stlc, _seas, (SELECT xchan FROM _chx WHERE chan = _chan),_v1ds, ((_rslt->'mostRelevantCustomerPriceInfo')->'source')->>'v1ds'),'{}'::jsonb) INTO _prem; + --_rslt := _rslt||_prem; + --RAISE NOTICE 'list: %', jsonb_pretty(_list); + RETURN _rslt; END; diff --git a/sql/get_hist.pg.sql b/sql/get_hist.pg.sql new file mode 100644 index 0000000..740dbeb --- /dev/null +++ b/sql/get_hist.pg.sql @@ -0,0 +1,151 @@ +CREATE OR REPLACE FUNCTION rlarp.get_hist(_mold text, _v1ds text, _cust text, _chan text) +RETURNS jsonb +LANGUAGE plpgsql +AS $func$ +DECLARE + _result jsonb; +BEGIN +WITH +--sel AS (select 'v1:P.P.PLT..' _v1ds, 'ALTMAN PLANTS' _cust, 'XNT0TQT3' _mold, 'D' _chan) +sort AS ( + SELECT + p.agglevel + ,CASE WHEN p.agglevel ? 'cust' THEN 'cust' ELSE 'market' END source + ,COALESCE(gset.v1ds = _v1ds,false) v1ds_match + ,gset.chan = _chan chan_match + ,gset.* + ,row_number() OVER (PARTITION BY p.agglevel ORDER BY avgunits DESC) rn + ,stats.* + FROM + rlarp.price_pool_dev p + JOIN LATERAL jsonb_to_record(gset) AS gset( + chan text + ,mold text + ,v1ds text + ,v0ds text + ,cust text + ,vers text + --,nurs text + --,ghse text + ) ON TRUE + JOIN LATERAL jsonb_to_record(stats) AS stats( + avgunits numeric + ,avgtargetprice numeric + ,avgordcount numeric + ,avgcustcount numeric + ,early_season int + ,early_price numeric + ,recent_season int + ,recent_price numeric + ) ON TRUE + WHERE + gset @> jsonb_build_object( + 'mold', _mold + ,'vers', 'A' + ) + AND ( + gset @> jsonb_build_object( + 'cust', _cust + ) + OR NOT gset ? 'cust' + ) + AND COALESCE(stats.early_season,stats.recent_season) IS NOT NULL + AND NOT p.agglevel ? 'nurs' + AND NOT p.agglevel ? 'ghse' + ORDER BY + source ASC + ,rn ASC +) +,flag AS ( +SELECT + --agglevel + CASE source + WHEN 'cust' THEN + CASE WHEN v1ds IS NOT NULL THEN + CASE WHEN v1ds_match THEN 'customer exact' ELSE + CASE WHEN rn = 1 THEN 'customer v1ds vol' ELSE 'customer v1ds other' END + END + ELSE + CASE WHEN rn = 1 THEN 'customer v0ds vol' ELSE 'customer v0ds other' END + END + ELSE + CASE WHEN v1ds IS NOT NULL THEN + CASE WHEN v1ds_match THEN 'market exact' ELSE + CASE WHEN rn = 1 THEN 'market v1ds vol' ELSE 'market v1ds other' END + END + ELSE + CASE WHEN rn = 1 THEN 'market v0ds vol' ELSE 'market v0ds other' END + END + END relevance + ,source + ,v1ds_match + ,chan_match + ,chan + ,mold + ,v1ds + ,v0ds + ,cust + ,vers + ,rn + ,avgunits + ,avgordcount + ,avgcustcount + ,avgtargetprice + ,early_season + ,early_price + ,recent_season + ,recent_price +FROM + sort +) +,rel AS ( + SELECT * FROM (values + ('customer exact' ,1) + ,('customer v0ds other',7) + ,('customer v0ds vol' ,3) + ,('customer v1ds other',6) + ,('customer v1ds vol' ,2) + ,('market exact' ,4) + ,('market v0ds other' ,9) + ,('market v0ds vol' ,5) + ,('market v1ds other' ,8) + ) x (flag,prefer) +) +,rel_sort AS ( + SELECT + -- flag.relevance + --,flag.source + --,rel.prefer + --,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC) best + jsonb_strip_nulls( + jsonb_build_object( + relevance + ,jsonb_build_object( + 'avgunits' ,avgunits + ,'avgordcount' ,avgordcount + ,'avgcustcount' ,avgcustcount + ,'avgtargetprice' ,avgtargetprice + ,'early_season' ,early_season + ,'early_price' ,early_price + ,'recent_season' ,recent_season + ,'recent_price' ,recent_price + ,'ds' ,COALESCE(v1ds,v0ds) + ,'rank' + ,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC) + ) + ) + ) doc + FROM + flag + LEFT OUTER JOIN rel ON + rel.flag = flag.relevance + WHERE + relevance ~ 'vol|exact' +) +--SELECT jsonb_pretty(jsonb_agg(doc)) FROM rel_sort +SELECT jsonb_obj_aggc(doc) INTO _result FROM rel_sort; + +RETURN _result; + +END +$func$; diff --git a/sql/gethist.sql b/sql/gethist.sql index f385aeb..a90845f 100644 --- a/sql/gethist.sql +++ b/sql/gethist.sql @@ -22,8 +22,10 @@ BEGIN gset, (SELECT string_agg(ae.v, '.') FROM jsonb_array_elements_text(p.agglevel) ae(v)) AS agglvl, season, + stats, (SELECT doc FROM getj) AS gdoc - FROM rlarp.price_pool_dev p + FROM + rlarp.price_pool_dev p WHERE gset @> jsonb_build_object( 'mold', (SELECT doc->>'mold' FROM getj), @@ -41,7 +43,7 @@ BEGIN SELECT jsonb_build_object( agg.agglvl, - jsonb_agg(gset || jsonb_build_object('season', season)) + jsonb_agg(gset || jsonb_build_object('season', season,'stats',stats)) ) AS data, gdoc FROM agg diff --git a/sql/gethist_table.pg.sql b/sql/gethist_table.pg.sql index 653c2bc..965b61e 100644 --- a/sql/gethist_table.pg.sql +++ b/sql/gethist_table.pg.sql @@ -1,45 +1,141 @@ WITH -getj AS ( - SELECT - ( - SELECT - jsonb_build_object('mold',JSON_AGG(DISTINCT stlc)) doc - FROM - "CMS.CUSLG".itemm - WHERE - item ~ 'TUH10000A10B04' - ) || - ( - SELECT - jsonb_build_object('cust',JSONB_AGG(DISTINCT c.dba)) - FROM - rlarp.cust c - WHERE - c.dba ~ 'DIAMOND R' - ) doc -) -,agg AS ( +sel AS (select 'v1:P.P.PLT..' _v1ds, 'ALTMAN PLANTS' _cust, 'TFR001G0' _mold, 'D' _chan) +,sort AS ( SELECT - gset - ,(SELECT string_agg(ae.v,'.') FROM jsonb_array_elements_text(p.agglevel) ae(v)) agglvl - ,season - --,(select doc from getj) gdoc + p.agglevel + ,CASE WHEN p.agglevel ? 'cust' THEN 'cust' ELSE 'market' END source + ,COALESCE(gset.v1ds = (SELECT _v1ds FROM sel),false) v1ds_match + ,gset.chan = _chan chan_match + ,gset.* + ,row_number() OVER (PARTITION BY p.agglevel ORDER BY avgunits DESC) rn + ,stats.* FROM rlarp.price_pool_dev p - WHERE - --gut the exact mold and actuals only + CROSS JOIN sel + JOIN LATERAL jsonb_to_record(gset) AS gset( + chan text + ,mold text + ,v1ds text + ,v0ds text + ,cust text + ,vers text + --,nurs text + --,ghse text + ) ON TRUE + JOIN LATERAL jsonb_to_record(stats) AS stats( + avgunits numeric + ,avgtargetprice numeric + ,avgordcount numeric + ,avgcustcount numeric + ,early_season int + ,early_price numeric + ,recent_season int + ,recent_price numeric + ) ON TRUE + WHERE gset @> jsonb_build_object( - 'mold',(SELECT doc->'mold'->>0 FROM getj), - 'vers','A' + 'mold', (SELECT _mold FROM sel) + ,'vers', 'A' ) - --pull either the exact customer or no customer AND ( gset @> jsonb_build_object( - 'cust',(SELECT doc->'cust'->>0 FROM getj) + 'cust', (SELECT _cust FROM sel) ) OR NOT gset ? 'cust' ) - ORDER BY - agglevel ASC + AND COALESCE(stats.early_season,stats.recent_season) IS NOT NULL + AND NOT p.agglevel ? 'nurs' + AND NOT p.agglevel ? 'ghse' + ORDER BY + source ASC + ,rn ASC ) -SELECT * FROM agg +--,flag AS ( +--SELECT +-- --agglevel +-- CASE source +-- WHEN 'cust' THEN +-- CASE WHEN v1ds IS NOT NULL THEN +-- CASE WHEN v1ds_match THEN 'customer exact' ELSE +-- CASE WHEN rn = 1 THEN 'customer v1ds vol' ELSE 'customer v1ds other' END +-- END +-- ELSE +-- CASE WHEN rn = 1 THEN 'customer v0ds vol' ELSE 'customer v0ds other' END +-- END +-- ELSE +-- CASE WHEN v1ds IS NOT NULL THEN +-- CASE WHEN v1ds_match THEN 'market exact' ELSE +-- CASE WHEN rn = 1 THEN 'market v1ds vol' ELSE 'market v1ds other' END +-- END +-- ELSE +-- CASE WHEN rn = 1 THEN 'market v0ds vol' ELSE 'market v0ds other' END +-- END +-- END relevance +-- ,source +-- ,v1ds_match +-- ,chan_match +-- ,chan +-- ,mold +-- ,v1ds +-- ,v0ds +-- ,cust +-- ,vers +-- ,rn +-- ,avgunits +-- ,avgordcount +-- ,avgcustcount +-- ,avgtargetprice +-- ,early_season +-- ,early_price +-- ,recent_season +-- ,recent_price +--FROM +-- sort +--) +--,rel AS ( +-- SELECT * FROM (values +-- ('customer exact' ,1) +-- ,('customer v0ds other',7) +-- ,('customer v0ds vol' ,3) +-- ,('customer v1ds other',6) +-- ,('customer v1ds vol' ,2) +-- ,('market exact' ,4) +-- ,('market v0ds other' ,9) +-- ,('market v0ds vol' ,5) +-- ,('market v1ds other' ,8) +-- ) x (flag,prefer) +--) +--,rel_sort AS ( +-- SELECT +-- -- flag.relevance +-- --,flag.source +-- --,rel.prefer +-- --,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC) best +-- jsonb_strip_nulls( +-- jsonb_build_object( +-- relevance +-- ,jsonb_build_object( +-- 'avgunits' ,avgunits +-- ,'avgordcount' ,avgordcount +-- ,'avgcustcount' ,avgcustcount +-- ,'avgtargetprice' ,avgtargetprice +-- ,'early_season' ,early_season +-- ,'early_price' ,early_price +-- ,'recent_season' ,recent_season +-- ,'recent_price' ,recent_price +-- ,'ds' ,COALESCE(v1ds,v0ds) +-- ,'rank' +-- ,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC) +-- ) +-- ) +-- ) doc +-- FROM +-- flag +-- LEFT OUTER JOIN rel ON +-- rel.flag = flag.relevance +-- WHERE +-- relevance ~ 'vol|exact' +--) +----SELECT jsonb_pretty(jsonb_agg(doc)) FROM rel_sort +----SELECT jsonb_pretty(jsonb_obj_aggc(doc)) FROM rel_sort +SELECT * FROM sort diff --git a/sql/price_pool.sql b/sql/price_pool.sql index 40e3806..889d505 100644 --- a/sql/price_pool.sql +++ b/sql/price_pool.sql @@ -22,6 +22,7 @@ CREATE TABLE IF NOT EXISTS rlarp.price_pool_dev AS ( ,round(sum(o.qty),0) units ,round(sum(o.sales_usd),0) sales_usd ,round(sum(COALESCE(tp.target_price,tq.target_price) * o.qty),2) target_price + ,count(DISTINCT o.ordnum) ordcount FROM rlarp.osm_stack o INNER JOIN "CMS.CUSLG".itemm i ON @@ -52,6 +53,7 @@ CREATE TABLE IF NOT EXISTS rlarp.price_pool_dev AS ( WHERE o.version IN ('Actual','Quotes') AND o.oseas >= 2015 + AND o.dsm <> 'PW' --AND o.part like 'SQL035%' --AND o.calc_status <> 'CANCELED' --AND o.fs_line = '41010' @@ -93,8 +95,10 @@ CREATE TABLE IF NOT EXISTS rlarp.price_pool_dev AS ( ,sum(units ) units ,sum(sales_usd) sales_usd ,round(sum(sales_usd )/sum(units),5) price_usd - ,round(sum(target_price)/sum(units),5) target_price + ,round(sum(target_price)/sum(units) FILTER (WHERE COALESCE(target_price,0) <> 0 ),5) target_price ,jsonb_agg(DISTINCT coltier) coltier + ,count(DISTINCT customer) custcount + ,sum(ordcount) ordcount FROM agg GROUP BY @@ -111,21 +115,54 @@ CREATE TABLE IF NOT EXISTS rlarp.price_pool_dev AS ( ,(oseas, version, baseitem, chanwide, v0dataseg, greenhouse_region ) ) ) - SELECT + ,find_stats AS ( + SELECT + gset + ,jsonb_object_agg(oseas,jsonb_build_object('units',units,'sales_usd',sales_usd,'price_usd',price_usd,'target_price',target_price)) season + ,(SELECT JSONB_AGG(k.v ORDER BY k.v ASC) FROM jsonb_object_keys(gset) k(v)) agglevel + ,round(avg(custcount),1) avgcustcount + ,round(avg(ordcount) ,1) avgordcount + ,round(avg(units) ,0) avgunits + ,round(avg(target_price),5) avgtargetprice + ,min(oseas) FILTER (WHERE oseas BETWEEN 2020 AND 2022)::text early_season + ,min(oseas) FILTER (WHERE oseas >= 2024)::text recent_season + --,oseas + --,units + --,sales_usd + --,price_usd + FROM + gsets + WHERE + oseas IS NOT NULL + --AND gset @> jsonb_build_object('mold', 'XNS0T1G3') + GROUP BY + gset + ) + SELECT gset - ,jsonb_object_agg(oseas,jsonb_build_object('units',units,'sales_usd',sales_usd,'price_usd',price_usd,'target_price',target_price)) season - ,(SELECT JSONB_AGG(k.v ORDER BY k.v ASC) FROM jsonb_object_keys(gset) k(v)) agglevel - --,oseas - --,units - --,sales_usd - --,price_usd + ,season + ,agglevel + ,jsonb_build_object( + 'avgcustcount' + ,avgcustcount + ,'avgordcount' + ,avgordcount + ,'avgunits' + ,avgunits + ,'avgtargetprice' + ,avgtargetprice + ,'early_season' + ,early_season::int + ,'early_price' + ,(season->early_season->>'price_usd')::numeric + ,'recent_season' + ,recent_season::int + ,'recent_price' + ,(season->recent_season->>'price_usd')::numeric + ) stats FROM - gsets - WHERE - oseas IS NOT NULL - --AND gset @> jsonb_build_object('baseitem', 'XNS0T1G3') - GROUP BY - gset + find_stats +--LIMIT 1000 ) WITH DATA; create index ppd_gset on rlarp.price_pool_dev using gin (gset);