How to convert calculated formula from salesforce to SQL - mysql

We have one Opportunity table in salesforce and this table has one calculated column called as "Is_XYZ".
Calculated formula for "Is_XYZ" column is -
calculatedFormula: IF(
AND(
OR(
AND(
UPPER(LeadSource__c) == 'XYZ',
DateValue(CreatedDate) > Date(2017,01,01)
),
AND( Is_PQR ,
IF(
Effective_Date__c <> null,
DateValue(CreatedDate) > Effective_Date__c ,
TRUE
),
IF(
Effective_Date__c <> null,
Effective_Date__c <= TODAY(),
TRUE
)
)
),
UPPER(MailingState) <> 'NY',
UPPER(Lead_Sub_Source__c) <> 'PQRS'
),
TRUE,
FALSE
)
We have created same Opportunity table in Hive SQL and we want to write select query to calculate "Is_XYZ" column value. We have converted formula from salesforce syntax to SQL syntax.
So, formula in SQL will be -
SELECT
IF(
(
(
( UPPER(LeadSource__c) == 'XYZ' AND
CreatedDate > '2017-01-01'
)
OR
( Is_PQR AND
IF( Effective_Date__c IS NOT NULL,
CreatedDate > Effective_Date__c,
TRUE
)
AND
IF( Effective_Date__c IS NOT NULL,
Effective_Date__c <= current_date,
TRUE
)
)
)
AND (UPPER(MailingState) <> 'NY')
AND (UPPER(Lead_Sub_Source__c) <> 'PQRS')
),
TRUE,
FALSE
) as Is_XYZ
FROM Opportunity;
Can you help me to confirm that both formulas(salesforce and SQL) are same? I mean, can you verify that both above formulas are doing same thing.
I tested it on both sides(salesforce and Hive SQL) and it is behaving differently. Values for that case are -
LeadSource__c = abcdef
Lead_Sub_Source__c = klmnop
CreatedDate = 2019-04-02T00:06:49.000Z
MailingState = HI
Is_PQR = true
Effective_Date__c = 2019-04-09
For above values, salesforce displays Is_XYZ = true and hive displays Is_XYZ = false. Please help me in identifying the issue.

I can tell that the date/time arithmetic is not correct, due to time components on the values. I don't know if this is the issue with your particular bad example.
For instance:
DateValue(CreatedDate) > Date(2017,01,01)
is not equivalent to:
CreatedDate > '2017-01-01'
The equivalence would be to:
CreatedDate >= '2017-01-02'
The issue is the DateValue() which removes the time component.
Similarly,
DateValue(CreatedDate) > Effective_Date__c ,
requires a modification.

Finally, we found that there is bug in Salesforce formula.
In Salesforce formula, we are checking "Effective_Date__c <> null" which is always returning false. In Salesforce, it is preferred to use IsBlank() function than IsNull().
So, we have changed CalculatedFormula in Salesforce to correct this issue. New formula will be - IsBlank(Effective_Date__c).
I am not a Salesforce developer, so not able to pick this bug earlier. After discussing this with Salesforce developer, we are able to find this bug which is present in system from last one year.
I found no way in Salesforce workbench to test/debug this Calculated field formula which is very frustrating.

Related

Sequelize returns different value than MySql result

I have something very odd happening and nothing seems to work. I have a SP in MySql that returns some results. When I run the SP in MySql workbench everything is correct. The query is quite long. But this is the LEFT JOIN is somehow creating the issues. I have other inner joins/left joins but they are fine.
SELECT DISTINCT Id.ReelTag
, Id.ECSPartNo
, WM.ShortDescription AS Description
, Id.ReelTagSerial
, group_concat(DISTINCT RA.UniqueID) AS UniqueID
, group_concat(DISTINCT coalesce(RA.OrdNo, Std.OrdNo)) AS OrdNo
, Id.Received
, IFNULL(Std.ReelQuantity,0) AS OriginalQuantity
, IFNULL(Id.Quantity,0) AS CurrentQuantity
, IFNULL(yest.Quantity,0) AS YesterdayQuantity
, IFNULL(cuts.Quantity,0) AS QuantityChanged
, cuts.OrdNo AS OrdNoChange
, IFNULL(CC.ShipQuantity,0) AS ShipQuantity
, CC.OrdNo AS OrdNo_Allocated
, IFNULL(Id.Quantity,0) - IFNULL(yest.Quantity,0) AS changeAOF_Yesterday
FROM InventoryDtl Id .....
LEFT JOIN (
SELECT
SourceReel
, SUM(CASE WHEN Action = 'Insert' THEN TotalQuantity
WHEN Action = 'Delete' THEN -TotalQuantity
ELSE 0 END) AS Quantity
, group_concat(DISTINCT CASE WHEN Action = 'Insert' THEN concat(OrdNo,'(Cut)') ELSE concat(OrdNo,'(UnCut)') END) AS OrdNo
FROM (
SELECT
Action
, SourceReel
, OrdNo
, SUM(Quantity) AS TotalQuantity
FROM CableCuts_Log CD
WHERE 1=1
AND 1 = CASE
WHEN SourceReel IS NOT NULL AND OrdNo LIKE 'E9%' AND Quantity > 0 AND DaTediff(Now(),LogDate) = 0 THEN 1
ELSE 0 END
GROUP BY Action, SourceReel, OrdNo
) CC
WHERE 1=1
GROUP BY SourceReel
) cuts ON Id.ReelTag = cuts.SourceReel
Again, When I run this in MySql workbench it's fine and loads in a second if that makes a difference.
But when I call my API to call the SP using ...
let inventoryReport = await models.sequelize
.query(
`call rpt_DailyInventoryReport($location, $byECSPartNo);`,
{ bind: {location: req.body.location, byECSPartNo: null} },
)
for(i=0;i<inventoryReport.length;i++) {
if(inventoryReport[i].ReelTagSerial == '6906' || inventoryReport[i].ReelTagSerial == '6858') {
console.log(inventoryReport[i]);
}
}
and exporting that into an Excel using ExcelJS, the 2 "cuts" columns from the query are essentially NULLs, because the return value of the "cuts" select are coming up NULLS, which is why it's giving the IFNULL value instead. Again this work in MySql workbench.
These are the values the API throws out.
{
"ReelTagSerial": 6858,
"CurrentQuantity": 700,
"YesterdayQuantity": 2500,
"QuantityChanged": 0,
"OrdNoChange": null,
"ShipQuantity": 0,
"OrdNo_Allocated": null,
"changeAOF_Yesterday": -1800
},
{
"ReelTagSerial": 6906,
"CurrentQuantity": 2730,
"YesterdayQuantity": 3330,
"QuantityChanged": 0,
"OrdNoChange": null,
"ShipQuantity": 0,
"OrdNo_Allocated": null,
"changeAOF_Yesterday": -600
},
Here are the 2 rows that their values should be.
{
"ReelTagSerial": 6906,
"CurrentQuantity": 2730,
"YesterdayQuantity": 3330,
"QuantityChanged": 600,
"OrdNoChange": E92021(Cut),
"ShipQuantity": 0,
"OrdNo_Allocated": null,
"changeAOF_Yesterday": -600
}
{
"ReelTagSerial": 6858,
"CurrentQuantity": 700,
"YesterdayQuantity": 2500,
"QuantityChanged": 1800,
"OrdNoChange": E912345(Cut),
"ShipQuantity": 0,
"OrdNo_Allocated": null,
"changeAOF_Yesterday": -1800
},
I have tried creating a temp table and defining the field type of varchar, text, mediumint for the QuantityChanged field.
At first I thought maybe ExcelJs was not liking the key/value pairs but then I simply console logged the 2 rows and they are returning like that from Sequelize. I have tried casting the 2 fields with every datatype possible.
, CAST(cuts.OrdNo AS char) AS OrdNoChange
, CAST(cuts.OrdNo AS binary) AS OrdNoChange
Now I am just immediately sending the return result as a response back to Postman and seeing all the rows to make sure for whatever reason those values are not being set in other rows. But they seem to be all good.
If I simply rearrange the columns so that the two bad fields get values of other fields, they do populate with their values, so that's about as far as I got. Or if I put just 1000 or a string type it returns correctly, so IT MUST be something to do with those 2 data types from the "cuts" query.
I have tried returning simply returning these from the "cuts" join query
SELECT
DISTINCT SourceReel
#, CAST(SUM(CASE WHEN Action = 'Insert' THEN TotalQuantity
# WHEN Action = 'Delete' THEN -TotalQuantity
# ELSE 0 END) AS UnSigned) AS Quantity
, SUM(TotalQuantity) AS Quantity
, OrdNo
#, group_concat(DISTINCT CASE WHEN Action = 'Insert' THEN concat(OrdNo,'(Cut)') ELSE concat(OrdNo,'(UnCut)') END) AS OrdNo
Nothing is working. Spent hours troubleshooting and searching...
Need some help please :)
Thanks in advance.
I was able to get around this by creating a table and inserting into it during the SP call. Then in NodeJs I created a model of that table and just used to find everything in the table immediately after I called the SP.
let inventoryReport = await models.Rpt_DailyInventory_Temp.findAll();
Then just TRUNCATE the table every time the SP is called.

mySQL Conditional Syntax Issue

Essentially I would like to determine a value based on a conditional and then use that value inside a different conditional all in the same select statement.
Example:
IF(IF (`date1` IS NOT NULL AND `date1 ` <> 0),
`date1`, `date2` AS processdate) = curdate(), "ready", "not ready" AS action_status
To determine processdate I am saying check the field date1 has a date, if so use it, otherwise use date2 as processdate.
Once processdate is determined, compare it to todays date, if they are equal set action_status = "ready", otherwise "not ready".
I believe the syntax is incorrect, what is the correct format for something like this?
AS can only apply to an entire expression for a return value of the select; you can't embed it in an expression. And each IF needs parentheses around its three arguments. So:
IF(
curdate() =
IF(
`date1` IS NOT NULL AND `date1 ` <> 0,
`date1`,
`date2`
),
"ready",
"not ready"
) AS action_status
(I changed ... = curdate() to be curdate() = ... just because I think it's more readable that way; either would work.)

SSRS - Expression to count the rows for currentdate match or (parameter selected date) with some equivalent other columns

In SSRS Expression, how to count the numbers of rows that present in today or yesterday in dataset with other equivalent condition,
For example
=COUNT(IIF(
DateDiff(DateInterval.Day,Cdate("01/01/1900"),Fields!Opendate.Value) =
DateDiff(DateInterval.Day,Cdate("01/01/1900"), Now()), Fields!Opendate.Value, Nothing))
Using this expression I can check get the total count for today, it's working.
I need to add to check today date with other condition like:
If (today date and Fields!reason.Value = "Other")
It's not working when I add reason value to check :
=COUNT(IIF(
DateDiff(DateInterval.Day, Cdate("01/01/1900"), Fields!Opendate.Value) =
DateDiff(DateInterval.Day, Cdate("01/01/1900"), Now()) -1, Fields!Opendate.Value, Nothing ) **And Fields!reason.Value = "Other"**)
Please guide me
Just add it in your IIF() statement:
=COUNT(IIF(
DateDiff(DateInterval.Day, Cdate("01/01/1900"), Fields!Opendate.Value) =
DateDiff(DateInterval.Day, Cdate("01/01/1900")
And Fields!reason.Value = "Other",
Now()) -1,
Fields!Opendate.Value,
Nothing
)
)

How to Change Select Query Value to Text using MySQL?

Take a look at the following query. How do you display Column 'Action' as text.
If the result of 'Action' is LEQ 0 then dipslay the text "Crash" and if 'Action'
is GRT 0 display the text "Hold"?
SELECT col1 AS Action
FROM vdk
WHERE t_stamp Between "{StartTime}" AND "{EndTime}"
Refactoring the answer above, since i don't see the necessity to add a query to an alias table. I think this should work the other answer should work too btw, but its a little more complicated query for no given reason.
SELECT (CASE WHEN col1 <= 0 THEN 'Crash' ELSE 'Hold' END) AS Action
FROM vdk
WHERE t_stamp Between "{StartTime}" AND "{EndTime}"
Use CASE WHEN ... ELSE ... END and select from your set (query):
SELECT *, (CASE WHEN Action <= 0 THEN 'Crash' ELSE 'Hold' END) as ActionText
FROM (
SELECT col1 AS Action
FROM vdk
WHERE t_stamp Between "{StartTime}" AND "{EndTime}"
) q
This application is similar to my first question and I thought it might help someone else down the the road.
User can select from a Table's Drop Down List a set of options to enter a value into the Database.
Using Ignition's Power Table Component's Extension Function configureEditor with the following script.
This script sets up the Drop Down List.
if colName == 'Action':
return {options': [(0, 'Null'), (1, 'HOLD'), (2, 'CRASH')]}
Along with the same Power Table's Extension Function onCellEdited script.
This script enters the selection as a value into the database.
#onCellEdited Upadte Query
row = rowIndex
col = colIndex
colName = colName
value = newValue
ndx = self.data.getValueAt(row,0)
query = "UPDATE vdk SET %s = ? WHERE ndx = ?" % colName
system.db.runPrepUpdate(query,[value,ndx],'history')
system.db.refresh(self.data)

SSRS Multi Groups Using Parameter in Expression

In Report Builder, I have a report with many parameters, three of the parameters are #DateFrom, #DateTo, #Check
The query from the Main dataset gives this result with 3 columns: Name, Check, ExpiryDate.
Name Check ExpiryDate
A Y 05/01/2016
B N 06/10/2017
C Y 08/15/2017
D N 08/20/2017
E Y 09/05/2017
F N 10/20/2018
I need to group the report into 3 groups based on the parameter values,
For example, the user runs the report would enter: #DateFrom = 08/1/2017 #DateTo: 08/31/2017
=> The report should look like below:
Group Current Range ExpiryDate [(ExpiryDate >= #DateFrom and ExpiryDate <=#DateTo) and Check = #Check ]
C Y 08/15/2017
D N 08/20/2017
Group Before Range ExpiryDate and Check = 'Y' [(ExpiryDate <= #DateFrom) and Check = 'Y']
A Y 05/01/2016
Group After Range ExpiryDate and Check = 'Y' [(ExpiryDate >= #DateTo) and Check = 'Y']
E Y 09/05/2017
In the tablix using the Main dataset (only one tablix in the report), there is one RowGroup named 'Details'
I read lots of arcticles and I tried many ways, but nothing worked as I could not find the right way I guess. Will you be able to help?
The easiest way to create another group is to modify the SQL and add another column with your grouping logic.
SELECT
....,
CASE
WHEN ExpiryDate BETWEEN #DateFrom AND #DateTo AND Check = #Check
THEN 'Current'
WHEN ExpiryDate <= #DateFrom AND Check = 'Y'
THEN 'Before'
WHEN ExpiryDate >= #DateTo AND Check = 'Y'
THEN 'After'
END as MyGroup,
...
FROM ...
so that you can create a parent group inside your tablix with the new custom grouping field.
OR if the SQL is very complex or you are using a shared dataset/stored procedure, then add a group to the SSRS tablix and specify a custom expression with similar logic using the SWITCH construct.
Edit, adding parameters to the SQL CASE
CASE
WHEN expirydate BETWEEN #DateFrom AND #DateTo AND [check] IN #check
THEN 'Current'
WHEN expirydate <= #FromDate AND [check] = 'Y'
THEN 'Before'
WHEN expirydate >= #FromDate and [check] = 'Y'
THEN 'After'
END as MyGroup
Note that check is only surrounded by square brackets because it's a reserved SQL keyword.