How to use Precision and Scalling while performing multiplcation and division of decimal number in DB2 - casting

I have a table data as below
+------+----------+---------------+
| col1 | col2 | col3 |
+------+----------+---------------+
| 1 | 32679050 | 1017593887.44 |
| 1 | 45756670 | 917011235.08 |
+------+----------+---------------+
I'm trying to multiply and divide the above table data as follows and reciving the error as **SQLCODE=-802, SQLSTATE=22003**
Select col1, decimal(sum(col2)*sum(col3),17,2) as col2, decimal(sum(col2)/sum(col3),17,2) as col3 from
table group by col1;
As i have understood the problem is coming from the precesion and scalling of the output column and could understood how does the precision and scalling work in DB2.
Any valuable leads would be helpful!!

select col1,decimal(sum(col2)*decimal(sum(col3),17,2),17,2) as col2,
decimal(sum(col2)/decimal(sum(col3),17,2),17,2) as col3 from table group by col1;
The above SQL query solved the problem.
So, I have converted the sum of decimal values to decimal and converted the result to either multiplication or division of decimal values to decimal again to acheive my final result.

Related

Summarize a table based on a column in another table

I have two tables in Power BI model
Table A
value1
value2
value3
....
value 1000
Table B
value 1 | 10
value 2 | 10
value 1 | 50
value 3 | 10
value 1 | -10
value 2 | 70
Can I make a new column (or measure) in Table A to Sum UP connected values ???
Expected RESULT:
value 1 | 50 --- (10+50-10)
value 2 | 80 --- (10+70)
value 3 | 10 --- (10)
Just something like SUM.IF in Excel, which can I drag to all rows ? Thanks in advance.
I tried to CALCULATE, but I can't do this for all different rows in Table A
You don't need Table A for this. SUMMARIZE() will create a column of distinct values to group by. Use the following Calculated Table. Note that this is NOT a MEASURE!
Result =
SUMMARIZE(
'Table B',
'Table B'[value ID],
"Sum", SUM('Table B'[number])
)
Yes, Possible ! Just Add a new column on your table, and write this DAX Code after relationship is created!

SAS: Check variables if they are not empty dynamically

I need help checking if several variables are not empty. Normally, a "where VarName is not missing" would suffice, however, the number of variables that are generated will vary.
I have the following macro I found which correctly determines the number of variables when called in a data step:
%macro var_count(var_count_name);
array vars_char _character_;
array vars_num _numeric_;
&var_count_name = dim(vars_char) + dim(vars_num);
%mend;
My datasets is creating a variable number of COLs (i.e. COL1, COL2, COL3, etc.) depending on the dataset I use. I would like to use this in a data step where it returns observations where each of my generated COL1, COL2, COL3, etc. variables are looked at. I envision something like below:
Data Want;
set Have;
where cats(COL, %var_count(total_vars)) is not missing;
run;
But this does not work. I would very much like to avoid having to write "where COL1 is not missing or COL2 is not missing or ..." everytime the program is run. Any and all help will be appreciated.
EDIT: I fear I may have been too unspecific in my needs above. I will try to be more clear below. Not sure if I should make a new post, but here goes.
Dataset that I have (CVal = Character value)
| ID | COL1 | COL2 | COL3 | COL4 | COL5 | COL6 | COL7 |
| 1 | | | | | | | CVal |
| 2 | CVal | CVal | | | | | |
| 3 | | | | | | | |
| 4 | | CVal | | | | | |
I would like to keep ID1, 2 and 4, due to there being information in either COL1 through COL7 in each of these.
Essentially I would like a piece of code that can do the following:
Data Want;
Set data have;
if missing(COL1) and missing(COL2) and missing(COL3) and missing(COL4)
and missing(COL5) and missing(COL6) and missing(COL7) then delete;
run;
My problem is then, the number of COLs will vary depending on the input dataset. It may sometimes just be COL1-COL5, sometimes COL1-COL20. How can this be made "automatic", so it will automatically register the number of COL-columns and then automatically check those columns, if they are all empty and then delete the observation.
In your case to test if any of the COL: variables is non-empty you can just test if the concatenation of them is non-empty.
data want;
set have;
if not missing(cats(of COL:));
run;
You need to use subsetting IF because you cannot use variable lists in a WHERE statement.
Example:
35 data test;
36 set sashelp.class;
37 where nmiss(of height weight) > 0 ;
------
22
76
ERROR: Syntax error while parsing WHERE clause.
ERROR 22-322: Syntax error, expecting one of the following: !, !!, &, (, ), *, **, +, ',', -, /, <, <=, <>, =, >, >=, ?, AND, BETWEEN, CONTAINS, EQ,
GE, GT, IN, IS, LE, LIKE, LT, NE, NOT, NOTIN, OR, ^, ^=, |, ||, ~, ~=.
ERROR 76-322: Syntax error, statement will be ignored.
38 run;
NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set WORK.TEST may be incomplete. When this step was stopped there were 0 observations and 5 variables.
WARNING: Data set WORK.TEST was not replaced because this step was stopped.
NOTE: DATA statement used (Total process time):
real time 0.02 seconds
cpu time 0.01 seconds
Note that if any of the COL... variables is numeric you would need to modify the test a little. When the MISSING option is set to ' ' then the line above will work. But if it is set to the normal '.' then the numeric missing values will appear as periods. If you don't mind also treating any character values that just have periods as missing also then you could just use compress() to remove the periods.
if not missing(compress(cats(of COL:),'.'));
You can use N to count the number of non-missing numerics and CATS to check for some character values being not-missing.
Example:
Presume numeric and character variables are segregated with prior variable based array statements such as
array chars col1-col7;
array nums x1-x10;
The subsetting if would be
if N(of vars_num(*)) or not missing (CATS(of vars_char(*)));
or test using COALESCE and COALESCEC
if not missing(coalesce(of nums(*))) or
not missing(coalesceC(of chars(*)));
If you don't know the variable names ahead of time, you will need to examine the data set ahead of the subsetting DATA step and codegen the array statements into macro variables.

Choose DAX measure based on slicer value

Is it possible to dynamically pick up appropriate DAX measure defined in a table by slicer value?
Source table:
+----------------+------------+
| col1 | col2 |
+----------------+------------+
| selectedvalue1 | [measure1] |
| selectedvalue2 | [measure2] |
| selectedvalue3 | [measure3] |
+----------------+------------+
The values of col1 I put into slicer. I can retrieve these values by:
SlicerValue = SELECTEDVALUE(tab[col1])
I could hard code:
MyVariable = SWITCH(TRUE(),
SlicerValue = "selectedvalue1" , [measure1],
SlicerValue = "selectedvalue2" , [measure2],
SlicerValue = "selectedvalue3" , [measure3],
BLANK()
)
But I do not want to hard code the relation SelectedValue vs Measure in DAX measure. I want to have it defined in the source table.
I need something like this:
MyMeasure = GETMEASURE(tab[col2])
Of course assuming that such a function exists and that only one value of col2 has been filtered.
#NickKrasnov mentioned calculation groups elsewhere. To automate the generation of your hard-coded lookup table, you could use DMVs against your pbix.
You might do something like below to get output formatted that can be pasted into a large SWITCH.
SELECT
'"' + [Name] + '", [' + [Name] + '],'
FROM $SYSTEM.TMSCHEMA_MEASURES

Inputting missing value in primary dataset based on values in secondary dataset and a matching condition

my understanding of SAS is very elementary. I am trying to do something like this and i need help.
I have a primary dataset A with 20,000 observations where Col1 stores the CITY and Col2 stores the MILES. Col2 contains a lot of missing data. Which is as shown below.
+----------------+---------------+
| Col1 | Col2 |
+----------------+---------------+
| Gary,IN | 242.34 |
+----------------+---------------+
| Lafayette,OH | . |
+----------------+---------------+
| Ames, IA | 123.19 |
+----------------+---------------+
| San Jose,CA | 212.55 |
+----------------+---------------+
| Schuaumburg,IL | . |
+----------------+---------------+
| Santa Cruz,CA | 454.44 |
+----------------+---------------+
I have another secondary dataset B this has around 5000 observations and very similar to dataset A where Col1 stores the CITY and Col2 stores the MILES. However in this dataset B, Col2 DOES NOT CONTAIN MISSING DATA.
+----------------+---------------+
| Col1 | Col2 |
+----------------+---------------+
| Lafayette,OH | 321.45 |
+----------------+---------------+
| San Jose,CA | 212.55 |
+----------------+---------------+
| Schuaumburg,IL | 176.34 |
+----------------+---------------+
| Santa Cruz,CA | 454.44 |
+----------------+---------------+
My goal is to fill the missing miles in Dataset A based on the miles in Dataset B by matching the city names in col1.
In this example, I am trying to fill in 321.45 in Dataset A from Dataset B and similarly 176.34 by matching Col1 (city names) between the two datasets.
I am need help doing this in SAS
You just have to merge the two datasets. Note that values of Col1 needs to match exactly in the two datasets.
Also, I am assuming that Col1 is unique in dataset B. Otherwise you need to somehow tell more exactly what value you want to use or remove the duplicates (for example by adding nodupkey in proc sort statement).
Here is an example how to merge in SAS:
proc sort data=A;
by Col1;
proc sort data=B;
by Col1;
data AB;
merge A(in=a) B(keep=Col1 Col2 rename=(Col2 = Col2_new));
by Col1;
if a;
if missing(Col2) then Col2 = Col2_new;
drop Col2_new;
run;
This includes all observations and columns from dataset A. If Col2 is missing in A then we use the value from B.
Pekka's solution is perfectly working, I add an alternative solution for the sake of completeness.
Sometimes in SAS a PROC SQL lets you skip some passages compared to a DATA step (with the relative gain in storage resources and computational time), and a MERGE is a typical example.
Here you can avoid sorting both input datasets and handling the renaming of variables (here the matching key has the same name col1 but in general this is not the case).
proc sql;
create table want as
select A.col1,
coalesce(A.col2,B.col2) as col2
from A left join B
on A.col1=B.col1
order by A.col1;
quit;
The coalesce() function returns the first non missing element encountered in the arguments list.

Compare Tables in BigQuery

How would I compare two tables (Table1 and Table2) and find all the new entries or changes in Table2.
Using SQL Server I can use
Select * from Table1
Except
Select * from Table2
Here a sample of what I want
Table1
A | 1
B | 2
C | 3
Table2
A | 1
B | 2
C | 2
D | 4
So, if I comparing the two tables I want my results to show me the following
C | 2
D | 4
I tried a few statements with no luck.
Now that I have your actual sample dataset, I can write a query that finds every domain in one table that is not on the other table:
https://bigquery.cloud.google.com/table/inbound-acolyte-377:demo.1024 has 24,729,816 rows. https://bigquery.cloud.google.com/table/inbound-acolyte-377:demo.1025 has 24,732,640 rows.
Let's look at everything in 1025 that is not in 1024:
SELECT a.domain
FROM [inbound-acolyte-377:demo.1025] a
LEFT OUTER JOIN EACH [inbound-acolyte-377:demo.1024] b
ON a.domain = b.domain
WHERE b.domain IS NULL
Result: 39,629 rows.
(8.1s elapsed, 2.04 GB processed)
To get the differences (given that tkey is your unique row identifier):
SELECT a.tkey, a.name, b.name
FROM [your.tableold] a
JOIN EACH [your.tablenew] b
ON a.tkey = b.tkey
WHERE a.name != b.name
LIMIT 100
For the new rows, one way is the one you proposed:
SELECT col1, col2
FROM table2
WHERE col1 NOT IN
(SELECT col1 FROM Table1)
(you'll have to switch to a JOIN EACH when Table1 gets too large)