ssrs nested IIF to compare the two Data sets - reporting-services

I need create a Delta Report which is based on the two data sets i.e DataSet1 and DataSet2.
I need take DataSet2 as reference if there is any change in any field value in DataSet1 I need change the color of the text box.
can anybody help me in this I wrote some code but its throwing Error.
=IIF(Fields!CIF.value, "DataSet1" = Fields!CIF.value, "DataSet2" AND Fields!Account_ID.value,"DataSet1" = Fields!Account_ID.value,"DataSet2",
IIF( Fields!Account_balance.value, "DataSet1" <> Fields!Account_balance.value, "DataSet2","Yellow","Transparent"),"Transparent","Transparent")

You can't mix datasets.
This will only work if your datasets each only have one row of data. Otherwise you'll need to figure out how to isolate the value you need.
=IIF(MAX(Fields!CIF.value, "DataSet1") = MAX(Fields!CIF.value, "DataSet2") AND MAX(Fields!Account_ID.value, "DataSet1") = MAX(Fields!Account_ID.value, "DataSet2"),
IIF(MAX(Fields!Account_balance.value, "DataSet1") <> MAX(Fields!Account_balance.value, "DataSet2"), "Yellow", "Transparent"), "Transparent")
Usually you'd have one dataset in a table and then look up the corresponding value in the other dataset.
If your CIF and Account ID are the common identifiers and you want to compate the Account Balances of each, I would base the table on dataset 1 and then bring in the value from dataset2 to compare. Combine the CIF and Account ID into a single text string for comparison.
Your color expression would then be something like:
=Lookup(Fields!CIF.value & "|" & Fields!Account_ID.value, Fields!CIF.value & "|" & Fields!Account_ID.value, Account_balance.value, "DataSet2")
SSRS:
Use Lookup to retrieve the value from the specified dataset for a
name-value pair where there is a 1-to-1 relationship. For example, for
an ID field in a table, you can use Lookup to retrieve the
corresponding Name field from a dataset that is not bound to the data
region.

Another approach would be to do this in a stored procedure and return the results as one dataset. For example, assume I have 10 fields in the tables. I can create a hash of the data for each record:
select
CASE WHEN chkHash2 = chkHash1 THEN 0 ELSE 1 END as 'ChgFlag'
,a.*
FROM
(
select
HASHBYTES('md5', t2.Field1 + t2.Field2 + ... + t2.Field10) as 'chkHash2'
,HASHBYTES('md5', t1.Field1 + t1.Field2 + ... + t1.Field10) as 'chkHash1'
,t1.Field1, t1.Field2, ... t1.Field10
From Table2 t2
LEFT JOIN Table1 t1 on t1.ID = t2.ID
) a
Big Assumption ... both tables have an ID that is unique and related.
This will give you a result set of Table1 (dataset1) fields and a flag that will tell you when any field has changed from Table2 (dataset2).
Depending on your application, this could be easier and faster. I always try to do the WORK in SQL as opposed to SSRS.

Related

bit operations in mysql

I am trying to create a simple filtering of records with bit operations by using this manual: https://dev.mysql.com/doc/refman/8.0/en/bit-functions.html
I have four properties that are defined and based on certain content:
Filter 1 (field1) gets the value 1 (binary 1)
Filter 2 (field2) gets the value 2 (binary 10)
Filter 3 (field3) gets the value 4 (binary 100)
Filter 4 (field4) gets the value 8 (binary 1000)
I set the values with an update:
UPDATE table SET filter = 1 where field1 = "a";
UPDATE table SET filter = filter|2 where field2 = "b";
UPDATE table SET filter = filter|4 where field3 = "c";
UPDATE table SET filter = filter|8 where field4 = "d";
Now the column is filled for the different properties. I now have values between 0 (no property applies) and 15 (all properties apply).
How do I manage to use them now? If I want to use e.g. the filters 1,2 and 4, I get with:
select * from table where filter = 1|2|8;
I get the value "11". But actually, "15" should also match, since all four properties are applied here.
I had no success with this, too:
select * from table where filter & (1|2|8);
Can someone help me? Or am I completely wrong?
Try WHERE (filter & (1|2|8)) = (1|2|8).
But please be aware that this bitmasking approach can't exploit indexes, so it will scale up poorly to megarow tables.

Use ValueA when JOIN returns a row, otherwise ValueB (like a default)

I have four tables for a form-builder in my databse.
fields (fieldID(PK), typeID, fieldName, ...) - This table is a row by row list of all fields to be in the form
fields_types (typeID(PK), htmlType, ...) - This is a table that links fields to html types (and other settings)
fields_meta (FieldMetaID(PK), FieldID, mName, mValue) - Additional settings for fields, but more specific. A textarea field might have a height attribute, but almost no other field would use that.
fields_tyeps_meta (TypeMetaID(PK), typeID, tmName, tmValue) - Defines what extraneous settings a field can have, and also supplies default values if it's not explicitly set)
So my Query currently looks something like this
SELECT *
FROM Fields F
JOIN Field_Types FT
on FT.FieldID = F.FieldID
LEFT
JOIN Field_Meta FM
on FM.FieldID = F.FieldID
I was wondering if there's a way to join Fields_Types_Meta so that when the row's JOIN to Fields_Meta doesn't return a row (no mValue), it returns tmValue
I realize I can use something like (CASE WHEN mValue = "" THEN tmValue ELSE mValue END) AS UseValue, but I might have fields where I want to allow the value to be set to empty.
Edit: I could probably do something with a subquery and COUNT, using a CASE decision based on that. It might not be the healthiest performance-wise, but this query runs and caches itself til server restart, or until it's told to run again (updates to form design)
It looks like you just want ¢oalesce():
coalesce(FM.mValue, FT.tmValue) as UseValue
When FM.mValue is null, coalesce() returns FT.tmValue instead.
If you have null values in FM that you want to preserve in the result set, then use a case expression instead:
case when FM.FieldID IS NULL THEN FT.tmValue ELSE FM.mValue END as UseValue
This phrases as: when the left join did find a match in FM, use mValue from that row (even if it is null), else use FT.tmValue.

Updates and Self Joins and Case Statements - oh my

I think I may be trying to do too much with one query, and it's been driving me batty.
I have two tables, Source and Zip_Code. The Source table has a zip code field that can either be 3 or 5 digits.
If it's 3 digits, I need to join to the zip_code table's 3-digit field and set the Source's new_zip field to the zip_code table's corresponding 5-digit entry.
If it's 5 digits, I need to link to the zip_code table's 5-digit field (to make sure it's a valid zip code), then put that 5-digit number in the Source's new_zip field.
I already understand that you can't manipulate something you're updating, hence using a self-join to manipulate a copy. So now I need to create Source2, and join Source1, Source2, and Zip_Code tables.
UPDATE SOURCE1
INNER JOIN SOURCE2 ON SOURCE1_UID = SOURCE2_UID
INNER JOIN ZIP_CODE ON SOURCE1_ZIP =
(
SELECT
(
CASE WHEN LENGTH(SOURCE1.ZIP <4
THEN ZIP_CODE.3_DIGIT
ELSE ZIP_CODE.5_DIGIT
END
)
FROM SOURCE2
)
SET SOURCE1.NEW_ZIP =
(
CASE WHEN LENGTH(SOURCE1.ZIP <4
THEN ZIP_CODE.3_DIGIT
ELSE ZIP_CODE.5_DIGIT
END
)
I know I'm doing something majorly wrong, but I'm having a block as to where.
You're not naming the Source table in the query. You need to name the table and then give it an alias like Source1 if you have to refer to it twice.
But I don't think there's any need for the self-join.
There's no need for the subqueries, you can use conditionals in an ON clause.
UPDATE Source AS s
JOIN Zip_Code AS z ON
CASE WHEN LENGTH(s.zip) = 3
THEN z.3_digit
ELSE z.5_digit
END
SET s.new_zip = z.5_digit
Your description says that you always want to set new_zip to the 5-digit code, so there's no need for a CASE in the SET clause.

SSRS field color expression for updated values

In the above image, there are 2 rows for a single ID. I want them to be coloured for the updated field values as follows:
for id 100 Email was updated so this should be coloured as a different colour.
for 101 City was updated
for 102 City and State both are updated
I want to colour the updated fields as shown in the image above, in an SSRS report.
In SSRS you can use the Previous function to compare a value to the one in the previous row. For example you could use an expression like this for the background color:
=IIf(Fields!ID.Value = Previous(Fields!ID.Value) AND Fields!City.Value <> Previous(Fields!City.Value), "Red", "White")
If you can modify the dataset query, you can try something like below:
In same row you will get the previous values. Then, it will be much easier to use conditional statements. Below is for SQL Server (T-SQL), you can try similar if not using SQL Server.
Select t1.*
, t2.email as prev_email
, t2.city as prev_city
from table t1
left join table t2
on t1.id = t2.id
and t1.rownum = t2.rownum - 1
And, set the textbox fill expression with like for Email column:
=iif(isnothing(Fields!prev_email.Value) or Fields!email.Value = Fields!prev_email.Value,"White","Red")

Update when unchecked value is checked

I have a query where the report name and report id are both displayed This only applies when the reports are pre-checked. The values are populated in a datagrid. If the report is unchecked, only the name is displayed. I tried using the UPDATE keyword but I kept running into syntax error. I know that the small change to the query is simple, but I am having a tricky time attempting to display the reportid when the report is unchecked or basically reportvisible being 0. How do I work around this to show the reportid regardless of if it is checked or not?
valsql1 = "SELECT c.ReportID, c.COMPANYID, rl.REPORTNAME
FROM CompanyReportListTable c
right join ReportList rl on c.reportid = rl.ReportID
and reportvisible = 1
and CompanyID =" & DropDownList1.SelectedValue & "
where rl.ReportID in (
Select ReportID
from ReportList
where ReportVisible = 1
)
order by ReportName"
You're right joining exclusively on reportvisible = 1, and then you're specifically selecting only reportIDs with reportvisible = 1. You are twice-over filtering out rows with reportvisible = 0, so of course you aren't going to get reportids for those rows. You should add rl.reportvisible to the SELECT clause and remove reportvisible = 1 from the join and where clauses.
It is only a one word/two letter change. At the first SELECT statement, instead of c.ReportID, it should be rl.REPORTID. Refer back to the right join; y using a right join, it returns the selected rows from reportlist, matches it with crl table. Now we made it so reportID appears regardless if it matches or not. Kind of like report name/title