Power Query Replace null values with values from another column - powerquery

I am working with data imported from a pdf file. There is an extra column in the Power Query import (Data.Column7), containing data that belongs in the adjacent columns on either side (Data.Column6 and Data.Column8). Columns 6 and 8 have null values in the cells where the data was pushed into Column 7. I would like to replace the null values in Columns 6 and 8 with the correct data from Column 7, leaving all other values Columns 6 and 8 as is.
After looking at the post here:
Power Query / Power BI - replacing null values with value from another column
and watching this video:
https://www.youtube.com/watch?v=ikzeQgdKA0Q
I tried the following formula:
= Table.ReplaceValue(#"Expanded Data",null, each _[Data.Column7] ,Replacer.ReplaceText,{"Data.Column6","Data.Column8"})
(Note, "Expanded Data" is the last step before this Replace Value step.)
I am not getting any kind of syntax error, but the Replace Value step isn't doing anything at all. My null values in Columns 6 and 8 have not been replaced with the correct data from Column 7.
Any insight into how to achieve replacement would be greatly appreciated. Thank you.
(I should mention, I am a new Power Query user, so please be detailed and assume I know nothing!)

I'm sure there must be some way to do this with the ReplaceValue function, but I think it might be easier to do the following:
1: Create a new column with definition NewData6= if[Data.Column6]=null then [Data.Column7] else [Data.Column6]
2: Do the same thing for 8 : NewData8= if[Data.Column8]=null then [Data.Column7] else [Data.Column8]
3: Delete Data.Column6/7/8
4: Rename the newly made columns if neccesary.
You can do these steps either in the advanced editor, or just use the create custom column button in the add column tab.

If the columns are of the text data type, then it might have empty strings instead of actual nulls.
Try replacing null with "" in your formula.

Related

Showing converted Base64 (from hex) in an existing SQL Server 2019 view

I do voluntary work at an animal shelter. We have an application which uses a SQL Server 2019 database. I have created a view that includes a varbinary(max) column. The value in this column is a picture, stored in hexadecimal-format. I would like to convert this Hex-value to a base64-binary file and add these to the view as an extra column.
I found the perfect solution for my situation in SQL Server : hex to base64. The example provided converts 1 single hex-value into 1 base64-value. I now need to add this solution to my view, but I'm not having any success.
The offered solution:
DECLARE #TestBinHex varchar(max), #TestBinary varbinary(max), #Statement nvarchar(max);
SELECT #TestBinHex = '0x012345';
SELECT #Statement = N'SELECT #binaryResult = ' + #TestBinHex;
EXECUTE sp_executesql #Statement, N'#binaryResult varbinary(max) OUTPUT', #binaryResult=#TestBinary OUTPUT;
SELECT
CAST(N'' AS XML).value(
'xs:base64Binary(xs:hexBinary(sql:column("bin")))'
, 'VARCHAR(MAX)'
) Base64Encoding
FROM
(SELECT #TestBinary AS bin) AS bin_sql_server_temp;
A simplified version of my view:
SELECT
a.cat_id, a.catname, s.cat_id,
s.stay_id, s.shelter_handler, s.shelter_kennel, s.picture
FROM
dbo.animal AS a
OUTER APPLY
(SELECT TOP 1 *
FROM dbo.shelterdata
WHERE a.cat_id = s.cat_id
ORDER BY s.stay_id DESC) AS S
WHERE
(a.cat_id IS NOT NULL) AND (s.leave_date IS NULL)
The view shows an overview of all cats currently present in the shelter (leave_date is NULL). The reason for the TOP 1 is that sometimes shelter animals get returned, and the application then assigns a new stay_id. To prevent duplicate values from the join, I only return the value of the most recent stay_id.
What I am trying to achieve: the second table (dbo.shelterdata) includes the picture, stored in hex value. I'd like to add a column Base64Encoding to the view which includes the converted value.
My attempts
I was successful in replacing the static value '0x012345' by a SELECT statement. But the way the solution is formatted, it only allows for one input value. So I had to restrict it with a WHERE clause. It is obvious to me that I need to make a subquery which inputs the hex value based on the unique cat_id. However, it has been many years since I worked with variable, so I'm struggling with the formatting of the statement.
My request
Does anyone have a suggestion how to build the conversion into the view?
Any assistance would be greatly appreciated.
After searching for a few more hours, I stumbled onto the solution. Maybe it will help someone else in the future. The solution is remarkably simple, as is often the case.
My view, mentioned above, is called dbo.shelter_view
select sv.picture,sv.cat_id,
cast('' as xml).value(
'xs:base64Binary(sql:column("sv.picture"))', 'varchar(max)'
) as Base64Encoding
from dbo.shelter_view as SV

Divide second row with first row value in the same column

I have a table with column Account.
Return 2 value :
4
2
I tried to divide 2/4 using expression
=Fields!Accounts.Value/Previous(Fields!Accounts.Value)
Something is not work here. Please point out what was wrong with it. Many thanks

How MAX of a concatenated column in oracle works?

In Oracle, while trying to concatenate two columns of both Number type and then trying to take MAX of it, I am having a question.
i.e column A column B of Number data type,
Select MAX(A||B) from table
Table data
A B
20150501 95906
20150501 161938
when I’m running the query Select MAX(A||B) from table
O/P - 2015050195906
Ideally 20150501161938 should be the output????
I am trying to format column B like TO_CHAR(B,'FM000000') and execute i'm getting the expected output.
Select MAX(A || TO_CHAR(B,'FM000000')) FROM table
O/P - 2015011161938
Why is 2015050195906 is considered as MAX in first case.
Presumably, column A is a date and column B is a time.
If that's true, treat them as such:
select max(to_date(to_char(a)||to_char(b,'FM000000'),'YYYYMMDDHH24MISS')) from your_table;
That will add a leading space for the time component (if necessary) then concatenate the columns into a string, which is then passed to the to_date function, and then the max function will treat as a DATE datatype, which is presumably what you want.
PS: The real solution here, is to fix your data model. Don't store dates and times as numbers. In addition to sorting issues like this, the optimizer can get confused. (If you store a date as a number, how can the optimizer know that '20141231' will immediately be followed by '20150101'?)
You should convert to number;
select MAX(TO_NUMBER(A||B)) from table
Concatenation will result in a character/text output. As such, it sorts alphabetically, so 9 appears after 16.
In the second case, you are specifiying a format to pad the number to six digits. That works well, because 095906 will now appear before 161938.

How to update a column with concatenate of two other column in a same table

I have a table with 3 columns a, b and c. I want to know how to update the value of third column with concatenate of two other columns in each row.
before update
A B c
-------------
1 4
2 5
3 6
after update
A B c
-------------
1 4 1_4
2 5 2_5
3 6 3_6
How can I do this in oracle?
Use the concatentation operator ||:
update mytable set
c = a || '_' || b
Or better, to avoid having to rerun this whenever rows are inserted or updated:
create view myview as
select *, a || '_' || b as c
from mytable
Firstly, you are violating the rules of normalization. You must re-think about the design. If you have the values in the table columns, then to get a computed value, all you need is a select statement to fetch the result the way you want. Storing computed values is generally a bad idea and considered a bad design.
Anyway,
Since you are on 11g, If you really want to have a computed column, then I would suggest a VIRTUAL COLUMN than manually updating the column. There is a lot of overhead involved with an UPDATE statement. Using a virtual column would reduce a lot of the overhead. Also, you would completely get rid of the manual effort and those lines of code to do the update. Oracle does the job for you.
Of course, you will use the same condition of concatenation in the virtual column clause.
Something like,
Column_c varchar2(50) GENERATED ALWAYS AS (column_a||'_'||column_b) VIRTUAL
Note : There are certain restrictions on its use. So please refer the documentation before implementing it. However, for the simple use case provided by OP, a virtual column is a straight fit.
Update I did a small test. There were few observations. Please read this question for a better understanding about how to implement my suggestion.

How to Repeat table in one report side

I have a simple report (1 Table with 2 small columns)
the report works fine but now I'm trying to repeat the table on the same page but I can't find an example on how to do this.
I also crosses only one question about this problem, so maybe I miss something obviously on how to solve this.
Could somebody please enlight me?
You can 'play' with (a single) Tablix details to simulate table repetition.
For example you can create 3 rows of details like this:
row 1: header
row 2: value
row 3: footer space
To obtain a result like this:
You can also use a different layout, for example:
row 1: label/value for column 1
row 2: label/value for column 2
row 3: footer space
If you have a very small table you can also set report columns to fill horizontal space.
This is the result (simulating table repetitions but you can also use a simple Tablix with standard header/details):
This is the result if you use columns and a simple Tablix with standard header/details:

Resources