how to change mysql query to mongodb query - mongodb

I am trying to change that mysql query to mongodb format. I can't find an answer on how to do it. Please suggest a solution.
I've tried several ways, but it doesn't work, please help
I know I have to use a aggregate query, but it's difficult because I have a lot of subqueries. How should I configure the stage?
SELECT #rowcnt := COUNT(*) AS cnt
, SUM(keywordcount) AS total_k_count
, SUM(exposecount) AS total_exp, SUM(clickcount) AS total_cc
, IF( SUM(exposecount) = 0, 0, ROUND((SUM(clickcount) / SUM(exposecount))* 100, 2) ) AS total_cr
, IF( SUM(clickcount) = 0, 0, ROUND(SUM(cost) / SUM(clickcount)) ) AS total_ccost
, ROUND(SUM(cost)) AS total_cost
, SUM(COUNT) AS total_count, SUM(directcount) AS total_d_count, SUM(indirectcount) AS total_ind_count
, IF( SUM(clickcount) = 0, 0, ROUND( ( SUM(COUNT) / SUM(clickcount) ) * 100, 2) ) AS total_con_r
, IF( SUM(COUNT) = 0, 0, ROUND((SUM(cost) / SUM(COUNT))) ) AS total_con_expense
, SUM(conversioncost) AS total_con_cost, SUM(conversiondirectcost) AS total_con_d_cost, SUM(conversionindirectcost) AS total_con_ind_cost
, IF( SUM(cost) = 0, 0, ROUND( ( SUM(conversioncost) / SUM(cost) * 100 ) ) ) AS total_roas
FROM (
SELECT a.s_date
, a.master_id, REPLACE( c.media_name, '\'', '\`' ) AS media_name, a.media_code
, b.keywordcount, SUM(a.exposecount) AS exposecount, SUM(a.clickcount) AS clickcount, SUM(a.cost) AS cost
, IF( SUM(a.exposecount) = 0, 0, ROUND((SUM(a.clickcount) / SUM(a.exposecount))* 100, 2) ) AS clickrate
, IF( SUM(a.clickcount)= 0, 0, ROUND( (SUM(a.cost) / SUM(a.clickcount)) , 2) ) AS clickcost
, b.count, b.directcount, b.indirectcount
, IF( SUM(a.clickcount) = 0, 0, ROUND((b.count / SUM(a.clickcount))* 100, 2) ) AS conversionrate
, IF( b.count = 0, 0, ROUND((SUM(a.cost) / b.count)) ) AS conversionexpense
, b.conversioncost, b.conversiondirectcost, b.conversionindirectcost
, IF( SUM(a.cost) = 0, 0, ROUND(( b.conversioncost / SUM(a.cost)) * 100) ) AS roas
FROM TMP_Report AS a
LEFT OUTER JOIN (
SELECT nrc.media_code, COUNT(*) AS keywordcount, nrc.master_id, SUM(nrc.count) AS COUNT, SUM(nrc.directcount) AS directcount, SUM(nrc.indirectcount) AS indirectcount
, SUM(nrc.conversioncost) AS conversioncost, SUM(nrc.conversiondirectcost) AS conversiondirectcost, SUM(nrc.conversionindirectcost) AS conversionindirectcost
FROM (
SELECT nrc.media_code, nrc.s_date, nrc.master_id, nrc.keyword_id, SUM(nrc.count) AS COUNT, SUM(nrc.directcount) AS directcount, SUM(nrc.indirectcount) AS indirectcount
, SUM(nrc.cost) AS conversioncost, SUM(nrc.directcost) AS conversiondirectcost, SUM(nrc.indirectcost) AS conversionindirectcost
FROM TMP_ReportConv AS nrc
GROUP BY nrc.master_id, nrc.keyword_id, media_code, s_date
) AS nrc
INNER JOIN autoanswer.calendar AS c2 ON nrc.s_date = c2.cal_date
GROUP BY nrc.master_id, nrc.media_code
) AS b ON a.master_id = b.master_id AND a.media_code = b.media_code
LEFT OUTER JOIN naver.mst_media c ON a.media_code = c.media_id
WHERE a.s_date BETWEEN $get_s_date AND $get_e_date
GROUP BY a.master_id, a.media_code
) AS m;

I am not going to do your job, but this could be a starting point:
db.TMP_Report.aggregate([
{
$group: {
_id: {master_id: "$master_id", media_code: "$media_code"},
count: { $count: {} },
clickcount: { $sum: "$clickcount" },
exposecount: { $sum: "$exposecount" }
}
},
{
$set: {
total_cr: { $round: [{ $multiply: [{ $divide: ["$clickcount", {$cond: ["$exposecount", "$exposecount", null]}] }, 100] }, 2] }
}
}
])

Related

How to write a seek/keyset pagination query using sequelize for postgres dialect?

I have a raw SQL query written in pg-promise that looks as shown below
SELECT
f.feed_item_id,
pubdate,
link,
guid,
title,
summary,
author,
feed_id,
COALESCE(likes, 0) AS likes,
COALESCE(dislikes, 0) AS dislikes,
COALESCE(bullish, 0) AS bullish,
COALESCE(bearish, 0) AS bearish,
tags
FROM
feed_items f
LEFT JOIN
feed_item_likes_dislikes_aggregate l
ON f.feed_item_id = l.feed_item_id
LEFT JOIN
feed_item_bullish_bearish_aggregate b
ON f.feed_item_id = b.feed_item_id
WHERE
(
pubdate,
f.feed_item_id
)
< ($1, $2)
ORDER BY
pubdate DESC,
f.feed_item_id DESC LIMIT $3
How can I rewrite this query using sequelize?
My current attempt comes like this
FeedItem.findAll({
attributes: [
'feedItemId',
'pubdate',
'link',
'guid',
'title',
'summary',
'author',
'feedId',
'tags',
[sequelize.fn('COALESCE', sequelize.col('bullish'), 0), 'bullish'],
[sequelize.fn('COALESCE', sequelize.col('bearish'), 0), 'bearish'],
[sequelize.fn('COALESCE', sequelize.col('likes'), 0), 'likes'],
[sequelize.fn('COALESCE', sequelize.col('dislikes'), 0), 'dislikes'],
],
include: [{
model: FeedItemBullishBearishAggregate,
attributes: [],
}, {
model: FeedItemLikesDislikesAggregate,
attributes: [],
}],
order: [
['pubdate', 'DESC'],
['feedItemId', 'DESC']
],
limit: 1
}).then(a).catch(b)
How do I put that where condition in the above findAll expression?

CardinalityViolation when trying to use nested subqueries to retrieve JSON from Postgres using SQLAlchemy

I'm trying to translate the following Postgres query into Sqlalchemy 1.4:
SELECT json_build_object(
'type', 'FeatureCollection',
'features', json_agg(
json_build_object(
'type', 'Feature',
'geometry', geom,
'properties', (
select json_build_object(
'id', hi.id,
'responses', (
select json_object_agg(e.etype, er.response)
from expert e
inner join expertresponse er on e.id = er.expert_id
where infra_id = hi.id
),
'protections', (
select json_object_agg(p.ptype, i.pscore)
from protection p
inner join infraprotection i on p.id = i.protection_id
where infra_id = hi.id
)
)
)
)
)
) as allinfra
from hardinfra hi;
So I define the subqueries in the same order:
responses = (
db.session.query(
(func.json_object_agg(Expert.etype, Expert_Response.response)).label(
"responses"
)
)
.join(Expert_Response.exp)
.filter(Expert_Response.infra_id == Hardinfra.id)
.scalar_subquery()
)
protections = (
db.session.query(
(func.json_object_agg(Protection.ptype, Infra_Protection.pscore)).label(
"protections"
)
)
.join(Infra_Protection.prot)
.filter(Infra_Protection.infra_id == Hardinfra.id)
.scalar_subquery()
)
properties = db.session.query(
(
func.json_build_object(
"id", Hardinfra.id, "protections", protections, "responses", responses
).label("properties")
)
).scalar_subquery()
features = db.session.query(
(
func.json_build_object(
"type",
"Feature",
"geometry",
Hardinfra.geom,
"properties",
properties,
).label("features")
)
).scalar_subquery()
q = db.session.query(
func.json_build_object(
"type", "FeatureCollection", "features", func.json_agg(features)
)
)
However I get a (psycopg2.errors.CardinalityViolation) more than one row returned by a subquery used as an expression error when features is evaluated. I'm not even sure that properties and features need to be scalar subqueries (responses and protections certainly do), but I'm clearly also doing something else wrong, perhaps to do with correlating the inner Hardinfra refs to the outer ref? I'm not sureā€¦
It might be caused by redundant subqueries, you could try to remove the last two subqueries.
responses = (
db.session.query(
(func.json_object_agg(Expert.etype, Expert_Response.response)).label(
"responses"
)
)
.join(Expert_Response.exp)
.filter(Expert_Response.infra_id == Hardinfra.id)
.scalar_subquery()
)
protections = (
db.session.query(
(func.json_object_agg(Protection.ptype, Infra_Protection.pscore)).label(
"protections"
)
)
.join(Infra_Protection.prot)
.filter(Infra_Protection.infra_id == Hardinfra.id)
.scalar_subquery()
)
properties = func.json_build_object(
"id", Hardinfra.id, "protections", protections, "responses", responses
)
features = func.json_build_object(
"type",
"Feature",
"geometry",
Hardinfra.geom,
"properties",
properties,
)
q = db.session.query(
func.json_build_object(
"type", "FeatureCollection", "features", func.json_agg(features)
)
)

I keep getting a unexpected select error in my snosql statement

I keep getting an unexpected select error as well as an unexpected ON error in rows 61 AND 64 in my snowsql statement.
Not sure why if anyone can help that would be great. I've added the portion of my snowsql statement below.
I'm trying to use a select statement within a where clause is there a way to do this?
AS select
t1.sunday_date,
t1.sunday_year_month,
t1.sunday_month,
t1.dc,
t1.source_sku,
t1.Product_Family,
t1.Product_type,
t1.Product_Subtype,
t1.Material,
t1.Color,
t1.Size,
t1.EOL_Date,
t1.NPI_Date,
t1.period_start,
t1.period_month,
IIF( t4.period_start < t1.sunday_date, iif(ISNULL(ta.actual_quantity), 0, ta.actual_quantity),
IIF(ISNULL(tfc.SOPFCSTOVERRIDE ), iif(ISNULL(tf.Period_Start), 0, tf.dc_forecast) , tfc.SOPFCSTOVERRIDE
)) AS forecast_updated,
iif(ISNULL(tf.Period_Start),t4.period_start,tf.Period_Start) AS period_start_forecast,
iif(ISNULL(ti.VALUATED_UNRESTRICTED_USE_STOCK), 0, ti.VALUATED_UNRESTRICTED_USE_STOCK) AS inventory_quantity,
iif(ISNULL(ti.HCI_DS_KEYFIGURE_QUANTITY), 0, ti.HCI_DS_KEYFIGURE_QUANTITY) AS in_transit_quantity,
iif(ISNULL(ti.planned_quantity), 0, ti.planned_quantity) AS inbound_quantity,
iif(ISNULL(tbac.backlog_ecomm ), 0, tbac.backlog_ecomm) + iif(ISNULL(tbac_sap.backlog_sap_open), 0, tbac_sap.backlog_sap_open) AS backlog_quantity,
iif(ISNULL(ta.actual_quantity), 0, ta.actual_quantity) AS actual_quantity,
iif(ISNULL(tso.open_orders), 0, tso.open_orders) AS open_orders,
iif(ISNULL(tf.Period_Start), 0, tf.dc_forecast) AS forecast,
tfc.SOPFCSTOVERRIDE AS forecast_consumption,
iif(ISNULL(tpc.SHIP_DATE), 0, tpc.SHIP_DATE) AS production_current_week,
iif(ISNULL(tpc.SHIP_DATE), 0, tpc.SHIP_DATE) AS production_next_week,
NOW() AS updated_timestamp
FROM ( ( ( ( ( ( ( ( (
SELECT
e.sunday_date,
e.sunday_month,
e.sunday_year_month,
d.dc,
c.SOURCE_SKU,
c.Product_Family,
c.Product_Type,
c.Product_Subtype,
c.Material,
c.Color,
c.Size,
c.EOL_Date,
c.NPI_Date,
b.period_start,
b.period_month
FROM
(SELECT sunday_date, sunday_month, sunday_year_month FROM bas_report_date) AS e,
(SELECT distinct Week_Date AS period_start, DateSerial('445_Year','445_Month',1) AS period_month from inv_bas_445_Month_Alignment) AS b,
(SELECT source_sku AS source_sku, Product_Family, Product_Type, Product_Subtype, Material, Color, Size, EOL_Date, NPI_Date from inv_vw_product_dev ) AS c,
(SELECT dc AS dc FROM inv_bas_dc_site_lookup) AS d
WHERE b.period_start >=
( select
MIN(mt.Reference_Date )
FROM BAS_report_date tr
INNER JOIN inv_bas_445_Month_Alignment mt ON tr.sunday_month = DateSerial(mt.'445_Year',mt.'445_Month,1')
)
AND b.period_start <= DateAdd("ww", 26,e.sunday_date)
) t1
LEFT JOIN
(
SELECT
MATERIAL_NUMBER,
CINT(LOCATION_NUMBER) AS Int_Location_ID,
HCI_DS_KEYFIGURE_DATE,
HCI_DS_KEYFIGURE_QUANTITY,
PLANNED_QUANTITY,
VALUATED_UNRESTRICTED_USE_STOCK
FROM inv_vw_ibp_transit_inventorry_dev
) ti
You can replace the DateSerial() function
(which is from VBA / MS Access / Excel from the Microsoft universe)
with DATE_FROM_PARTS().
DATE_FROM_PARTS() also supports the non-obvious functionality of DateSerial():
DateSerial(2020, 1, 1 - 1) gets you New Year's Eve - the day before New Year's Day
DATE_FROM_PARTS(2020, 1 - 1, 1 - 1) is the month before the day before New Year's Day
DATE_FROM_PARTS(y, m + 1, 0) is End Of Month (EOM).
etc., etc.

DB2 merge upsert gets 'Row not found for MERGE' error

I am trying to do a basic upsert on an iSeries db2 with the MERGE statement, similar to as described in Does DB2 have an "insert or update" statement? and http://db2performance.blogspot.com/2011/12/merge-make-your-upserts-quick.html. When executed, it gives me Row not found for MERGE. SQLSTATE=02000 instead of inserting the row. Since I have when not matched then insert in the statement, why will it return an error instead of inserting? I looked all over SO and didn't see this particular issue.
Here is the statement I'm using:
merge into UFDFTRN as T using (
select * from UFDFTRN
where DFCNO = 354 and DFINV = 1179 and DFLC = 1 and DFDATE = '2017-01-31'
and DFSPLT = 0 and DFSEQ = 100
) as S on (
T.DFCNO = S.DFCNO and T.DFINV = S.DFINV and T.DFDATE = S.DFDATE and
T.DFSPLT = S.DFSPLT and T.DFSEQ = S.DFSEQ
) when matched then
update set DFSEQ = 1000, DFTRAN = 0, DFITEM = 'F224', DFRITM = '0',
DFDESC = 'DAIRY VTM PREMIX', DFQTY = 3, DFUM = '',DESIQU = 0, DFRTQU = 3,
DFUPR = 0, DFCTUP = 0, DFUCST = 0, DFOUCST = 0, DFAMT = 0, DFOAMT = 0, DFCODE = '',
DFURAT = '', DFCGCD = '0', DFCTNO = 0, DFADJITM = '', DFADJPCT = 0, DFMNFITM = '',
DFMNFRAT = '', DFMNFQTY = '0', DFMNFTQTY = '0'
when not matched then
insert (DFCNO, DFINV, DFLC, DFDATE, DFSPLT, DFSEQ, DFTRAN, DFITEM, DFRITM, DFDESC,
DFQTY, DFUM, DFSIQU, DFRTQU, DFUPR, DFCTUP, DFUCST, DFOUCST, DFAMT, DFOAMT, DFCODE,
DFURAT, DFCGCD, DFCTNO, DFADJITM, DFADJPCT, DFMNFITM, DFMNFRAT, DFMNFQTY, DFMNFTQTY
) values (
354, 1179, 1, '2017-01-31', 0, 1000, 0, 'F224', '0', 'DAIRY VTM PREMIX', 3, '', 0,
3, 0, 0, 0, 0, 0, 0, '', '', '0', 0, '', 0, '', '', '0', '0'
)
It probably should look more like this:
merge into UFDFTRN as T using (
select 354 DFCNO, 1179 DFINV, 1 DFLC, '2017-01-31' DFDATE, 0 DFSPLT, 100 DFSEQ
, 'DAIRY VTM PREMIX' f1 -- all other columns you might need
from sysibm.sysdummy1
) as S
on (
T.DFCNO = S.DFCNO and T.DFINV = S.DFINV and T.DFDATE = S.DFDATE and
T.DFSPLT = S.DFSPLT and T.DFSEQ = S.DFSEQ
)
when matched then
update set T.DFSEQ = S.DFSEQ, T.DFTRAN = S.DFTRAN, -- etc. etc.
when not matched then
insert (DFCNO, DFINV, ... -- etc. etc.
) values (
S.DFSNO, S.DFINV, ..., S.F1, ...-- etc. etc.
)
PS. Not tested.
Mustaccio has the right format for the merge...
But as I commented, that's a really funny way to use merge.
Personally, for a 1 time thing, I would have just
update UFDFTRN
set (DFCNO, DFINV, DFLC, DFDATE, DFSPLT, DFSEQ, DFTRAN, DFITEM, DFRITM, DFDESC,
DFQTY, DFUM, DFSIQU, DFRTQU, DFUPR, DFCTUP, DFUCST, DFOUCST, DFAMT, DFOAMT, DFCODE,
DFURAT, DFCGCD, DFCTNO, DFADJITM, DFADJPCT, DFMNFITM, DFMNFRAT, DFMNFQTY, DFMNFTQTY
) = (
354, 1179, 1, '2017-01-31', 0, 1000, 0, 'F224', '0', 'DAIRY VTM PREMIX', 3, '', 0,
3, 0, 0, 0, 0, 0, 0, '', '', '0', 0, '', 0, '', '', '0', '0'
)
where DFCNO = 354 and DFINV = 1179 and DFLC = 1 and DFDATE = '2017-01-31'
and DFSPLT = 0 and DFSEQ = 100
And if that failed with record not found, simply changed the update to an insert
insert into UFDFTRN
(DFCNO, DFINV, DFLC, DFDATE, DFSPLT, DFSEQ, DFTRAN, DFITEM, DFRITM, DFDESC,
DFQTY, DFUM, DFSIQU, DFRTQU, DFUPR, DFCTUP, DFUCST, DFOUCST, DFAMT, DFOAMT, DFCODE,
DFURAT, DFCGCD, DFCTNO, DFADJITM, DFADJPCT, DFMNFITM, DFMNFRAT, DFMNFQTY, DFMNFTQTY
) values (
354, 1179, 1, '2017-01-31', 0, 1000, 0, 'F224', '0', 'DAIRY VTM PREMIX', 3, '', 0,
3, 0, 0, 0, 0, 0, 0, '', '', '0', 0, '', 0, '', '', '0', '0'
)
This use case is not unusual at all. This is the most basic use case for merge imo. You're trying to update or insert into 1 table. It really should be easier but the solution is to put any where clause in the on () portion of the statement and it starts working as expected. (worked db2 luw 10.5 at least.. I have the exact same situation) Merge apparently can't handle the using () portion's where clause. It only sees what's in on () portion for the update/insert criteria. Don't follow sysdummy1 answer as that isn't determining if the data actually exists in the target table it's just text. I don't want to write an insert and check failure because it will cause the app to throw an error and I really shouldn't have to trap the error and do that code if db2 has this feature.

Expression of non-boolean type specified

Can't figure out why this query won't run, because its saying I don't have a Boolean statement where one should be.
The error I'm getting says:
An error occurred while executing the query.
An expression of non-boolean type specified in a context where a condition is expected, near 'AND'. (Microsoft SQL Server Report Builder)
Server Name: xxxxxxxxxx
Error Number: 4145
Severity: 15
State: 1
Line Number: 9
SELECT
REF_TPI_NPI_PHYS.MNE,
REF_TPI_NPI_PHYS.REFERRING,
RPT_MK_PRACT_PHYS_PT_CNT.COUNT_PTS AS TOTAL_PTS,
Sum(IIf(HBA1C_DATE IS NOT NULL, 1, 0)) AS COUNT_HBA1C,
Format((Sum(IIf(HBA1C_DATE IS NOT NULL, 1, 0)) / ([RPT_MK_PRACT_PHYS_PT_CNT].COUNT_PTS)), 'Percent') AS PANELED_HBA1C,
Format(Sum(IIf(HBA1C_VALUE IS NOT NULL AND IsNumeric(CAST(HBA1C_VALUE AS FLOAT)) AND CAST(HBA1C_VALUE AS FLOAT) <= 100, 1, 0))) / Sum(IIf(HBA1C_DATE IS NOT NULL, 1, 0)), 'Percent') AS HBA1C_COMP
Sum(IIf(LDL_DATE IS NOT NULL, 1, 0)) AS COUNT_LDL,
Format((Sum(IIf(LDL_DATE IS NOT NULL, 1, 0)) / ([RPT_MK_PRACT_PHYS_PT_CNT].COUNT_PTS)), 'Percent') AS PANELED_LDL,
Format(Sum(IIf(LDL_VALUE IS NOT NULL AND IsNumeric(CAST(LDL_VALUE AS FLOAT)) AND CAST(LDL_VALUE AS FLOAT) <= 100, 1, 0))) / Sum(IIf(LDL_DATE IS NOT NULL, 1, 0)), 'Percent') AS LDL_COMP
FROM
(
(
TBL_HBA1C_LDL LEFT JOIN TBL_REGISTRATION
ON CAST(RTRIM(LTRIM(TBL_HBA1C_LDL.PAT_MRN)) AS INTEGER) = TBL_REGISTRATION.MRN
)
LEFT JOIN
REF_TPI_NPI_PHYS
ON TBL_REGISTRATION.PCP = REF_TPI_NPI_PHYS.REFERRING
)
LEFT JOIN
RPT_MK_PRACT_PHYS_PT_CNT
ON TBL_REGISTRATION.PCP = RPT_MK_PRACT_PHYS_PT_CNT.PCP
GROUP BY
REF_TPI_NPI_PHYS.MNE,
REF_TPI_NPI_PHYS.REFERRING,
RPT_MK_PRACT_PHYS_PT_CNT.COUNT_PTS
ORDER BY
REF_TPI_NPI_PHYS.MNE,
REF_TPI_NPI_PHYS.REFERRING