How to mix 2 columns with data in one with NULLS involved QGIS - multiple-columns

I have 2 columns filled with different numbers, and I'd like to make a third column relocating the numbers that get repeated. There can also be a NULL in these columns, in that case I'd like to get the other result.
Here's an example.
Column A
Column B
1
2
2
2
3
NULL
NULL
4
NULL
NULL
I's like to join both columns in one (Column C) with the following rules.
Value A != Value B --> A string of characters looking like this '???'
Value A == Value B --> Get Value A or B, doesn't matter
Value A AND Value B = NULL --> Get Value A
Value A = NULL AND Value B --> Get Value B
Value A and B == NULL --> Get NULL
With this result, everything works fine except the first case shown before, where Column A has X value and Column B has Y value. I can't get the expected '???' result that I want.
Haven't tried using arrays.

So you are using the Field Calculator to compute the values for Column C from the values of Column A and Column B.
Note that QGIS Feature attributes have types they could be either integer, float, or text. Assuming your Column A and Column B are integers, then Column C would also be an integer column, therefore the value '???' would not be acceptable as this cannot be converted to an integer value.
One common approach to this is to reserve a specific value from the integer range as an additional INVALID DATA value. For instance if all your valid values are positive you could use -1 as your INVALID DATA value.
Then your code could look like this:
if( ("PUNTS INICIALS ed50_EQM1 C d" is NULL) or ("PUNTS FINALS ed50_EQM1 C d" is NULL),
coalesce("PUNTS INICIALS ed50_EQM1 C d","PUNTS FINALS ed50_EQM1 C d"),
if("PUNTS INICIALS ed50_EQM1 C d"="PUNTS FINALS ed50_EQM1 C d","PUNTS INICIALS ed50_EQM1 C d",-1))
Note that coalesce() can be used to handle the case when one of the values is NULL.

Related

SSRS report - Calculate a new field based on the value of a different field

I am relatively new to this and would appreciate some help.
What I am trying to do is take the current value of a field and multiply it by some factor based on the value of a different field.
For example, if I have one column (Column A) that has three different values (Z, X, and Y) and another column (Column B) with a variety of numbers, I want to calculate a third field (Column C) based on these two associated values. So if the value of column A is equal to 'Z' the value in Column C would be equal to Column B multiplied by 2. If the value in column A is equal to 'X' the value in Column C would be equal to the value in Column B multiplied by 1.5. Finally, if the value in column A is equal to 'Y' then the value in Column C would just be equal to the value in Column B.
Example of Question
Is there a way of doing this just as a calculated field?
Thanks in advance for any help!
Set the expression of the column to something like
= Fields!ColumnB.Value *
SWITCH(
Fields!ColumnA.Value = "X", 1.5,
Fields!ColumnA.Value = "Y", 1,
Fields!ColumnA.Value = "Z", 2,
True, 0
)
The True line acts like an ELSE so anything that does not match X, Y or Z will get multiplied by 0 (resulting in zero)

ssis swap some values in a data flow if they match a lookup table

Here's my problem - Midstream in my data flow, we have some values in one column that we want to swap for other values based on a lookup table.
For example, if I had a rowset like this:
Key Value
1 A
2 B
3 A
4 C
5 D
6 B
... ...
If I had a lookup table in a SQL Server DB that looked like this:
Value1 Value2
C Y
D Z
Then I would want my package to swap only those values so the resulting data flow would look like this:
Key Value
1 A
2 B
3 A
4 Y
5 Z
6 B
... ...
What components would produce the simplest solution?
You could use a lookup component and then:
Set it up to Ignore Failure
Values that do not match will return null for the lookup value
Use a derived column expression to populate where the lookup succeeded
ISNULL(Value2) ? Value : Value2

How to order mysql rows in custom order?

I want to order mysql records by one column whose values start with N,Y,F,P,U. Type of column is VARCHAR. I want to order by column according to first letter of this column's values.
Specific order is N - Y - F - P - U.
So first record must be that one with some column's value N, the second record has that column's value starting with Y and so on.
How to order by first letter of column's value?
SELECT
...
ORDER BY
CASE SUBSTR(one_column,1,1)
WHEN 'N' THEN 0
WHEN 'Y' THEN 1
WHEN 'F' THEN 2
WHEN 'P' THEN 3
WHEN 'U' THEN 4
ELSE 5
END
...or join to lookup table of values, or use IF functions to map the char to a number.

SUM of each row is counting null values as 0. How do I make mysql skip null values?

Well, the values aren't null per say, they are in VARCHAR(30) but in decimal form. However some of the records have "NA" in some fields. I would like mysql to skip those rows in SUM calculation when "NA" is present in the fields used for the SUM. Mysql is treating all incalculable fields as 0. The 0 from fields containing "NA" is misleading. I am doing a GROUP BY TABLE.ID.
Edit:
SELECT
SUM(
CASE
WHEN X >1 THEN 1
WHEN X<-1 THEN 2
ELSE 3
END
CASE
WHEN Y >1 THEN 1
WHEN Y <-1 THEN 2
ELSE 3
END)
AS "Col X+Y";
FROM TableA
GROUP BY TableA_ID;
Sometimes X and/or Y = "NA" on certain fields. I get 6 if both X and Y on TableA_ID = 17 or other numbers when one of them is "NA".
Edit (quoting my comment on VARCHAR):
"I tried storing my values as DEC(5,2), but some of the data from Excel have NA's in the fields. I did set X DEC(5,2) NULL and tried inserting NA into it but kept getting an error (cannot be null). I also tried making the default value "NA" but still get an error (cannot be null). I'll add in a sample query as edit."
I got it. I added in another WHERE clause using
WHERE ..... AND(Colx IS NOT NULL OR Coly IS NOT NULL OR ......);
I switched back the values to DEC(3,1) and made the fields NULLable with defaults null if the field value is NULL. I had to understand how to use NULL. I took out the 'NA's in Excel and left those field values blank.
if foo1 is null or NA just sum it as zero (the neutrum value in the addition), otherwise sum the value.
select sum( case when foo1 is null or foo1 = 'NA' then 0 else foo1 end) as sum, foo2
from FooTable group by foo2
or
select sum(foo1) from FooTable
where (foo2 <> 'NA' and foo2 is null) and (foo3 <> 'NA' or foo3 is null )
group by foo4

Complex - returning information that is not found in the database

I have a strange query to perform from a website. I have sets of arrays that contain pertinent ids from a many tables - 1 table per array. For example (the array name is the name of the table):
Array Set 1:
array "q": 1,2,3
array "u": 1,5
array "k": 7
Array Set 2:
array "t": 2,12
array "o": 8, 25
Array Set 3 (not really a set):
array "e": 5
I have another table, Alignment, which is not represented by the arrays. It performs a one to many relationship, allowing records from tables q,u, and k (array set 1, and recorded as relType/relID in the table) to be linked to records from t and o (array set 2, recorded as keyType/keyID) and e (array set 3, recorded as keyType/keyID). Example below:
Table: Alignment
id keyType keyID relType relID
1 e 5 q 1
2 o 8 q 1
3 o 8 u 1
4 t 2 q 2
5 t 2 k 7
6 t 12 q 1
So, in record 6, a record with an id of 12 from table t is being linked to a record with an id of 1 from table q.
I have to find missing links. The ideal state is that each of the ids from array set 1 have a record in the alignment table linking them to at least 1 record from array set 2. In the example, alignment record 1 does not count towards this goal, because it aligns a set 1 id to a set 3 id (instead of set 2).
Scanning the table, you can quickly see that there are some missing ids from array set 1: "q"-3 and "u"-5.
I've been doing this with script, by looping through each set 1 array and looking for a corresponding record, which generates a whole bunch of sql calls and really kills any page that calls this function.
Is there some way I could accomplish this in a single sql statement?
What would I like the results to look like (ideally):
recordset (consisting magically of data that didn't exist in the table):
relType | relID
q 3
u 5
However, I would be elated with even a binary type answer from the database - were all the proper ids found: true or false? (Though the missing records array is required for other functions, but at least I'd be able to choose between the fast and slow options).
Oh, MySQL 5.1.
User Damp gave me an excellent answer using a temporary table, a join, and an IS NULL statement. But it was before I added in the wrinkle that there was a third array set that needed to be excluded from the results, which also ruins the IS NULL part. I edited his sql statement to look like this:
SELECT *
FROM k2
LEFT JOIN alignment
USING ( relType, relID )
HAVING alignment.keyType IS NULL
OR alignment.keyType = "e"
I've also tried it with a Group By relID (i always thought that was a requirement of the HAVING clause). The problem is that my result set includes "q"-1, which is linked to all three types of records ("o","t", and "e"). I need this result excluded, but I'm not sure how.
Here's the sql I ended up with:
SELECT *
FROM k2
LEFT JOIN (
SELECT *
FROM alignment
WHERE keyType != 'e' and
(
(relType = 'q' AND relID IN ( 1, 2, 3 ))
OR
(relType = 'u' AND relID IN ( 1, 5 ))
OR
(relType = 'k' AND relID IN ( 7 ))
)
)A
USING ( relType, relID )
HAVING keyType Is Null
I have to dump the values for the IN qualifiers with script. The key was not to join to the alignment table directly.
You can try to go this route:
DROP TABLE IF EXISTS k2;
CREATE TEMPORARY TABLE k2 (relType varchar(10),relId int);
INSERT INTO k2 VALUES
('q',1),
('q',2),
('q',3),
('u',1),
('u',5),
('k',7);
SELECT * FROM k2
LEFT JOIN Alignment USING(relType,relId)
HAVING Alignment.keyType IS NULL
This should work well for small tables. Not sure about very large ones though...
EDIT
If you wanted to add a WHERE statement the query would be as follow
SELECT * FROM k2
LEFT JOIN Alignment USING(relType,relId)
WHERE Alignment.keyType != 'e'
HAVING Alignment.keyType IS NULL