TSQL Replace with Length Constraint - sql

So FIELD2 can return 2 groups of fields concatenated as a single result depending on the value of Mycondition.
My problem is only when Mycondition = 1
If MyCondition = 1 then I need to concatenate INT_FIELD_ONE + 'A' + INT_FIELD_TWO.
The concatenation is not the problem.
The problem is if INT_FIELD_ONE (is null) + 'A' + INT_FIELD_TWO (is null), then I have to return nothing.
My Replace command would work if both fields ONE and TWO are null. But if only 1 is NULL and the other is not the "A" gets deleted any way. The A needs to remain if 1 field is not null.
For Example:
NULL + 'A' + NULL = Nothing
NULL + 'A' + xxxx = Axxxx
xxxx + 'A' + NULL = xxxxA
Therefore I need to make a TSQL replace with a length constraint of result > 1
Any Ideas?
SELECT XXX,
CASE --Case Statement to Return Field2
WHEN MyCondition = 1 THEN
--Constraint on the Replace Starts Here
REPLACE(
Isnull(CAST(INT_FIELD_ONE AS VARCHAR), '') + 'A' +
Isnull(CAST(INT_FIELD_TWO AS
VARCHAR), '')
,'A','')
ELSE
REPLACE(
Coalesce(REPLACE(INT_FIELD_THREE, '', '-'), Isnull(INT_FIELD_THREE, '-'), INT_FIELD_THREE) +
' / ' + Coalesce(REPLACE(INT_FIELD_FOUR, '', '-'),
Isnull(INT_FIELD_FOUR, '-'), INT_FIELD_FOUR) + ' ', '- / - ',
'')
END
AS FIELD2
FROM TABLEX

how about this?
CASE WHEN MyCondition = 1 AND (INT_FIELD_ONE IS NOT NULL OR INT_FIELD_TWO IS NOT NULL) THEN concat..
WHEN MyCondition = 1 THEN NULL -- at that point we know that both are null
ELSE ... END
Notice that now you don't need the REPLACE function when you are doing the concat because you know for sure that one of your fields is not null

…
WHEN MyCondition = 1 THEN
ISNULL(
NULLIF(
ISNULL(CAST(int1 AS VARCHAR), '') + 'A' + ISNULL(CAST(int2 AS VARCHAR), ''),
'A'
),
''
)
…
When both int1 and int2 are NULL, the result of the concatenation will be A. NULLIF() will return NULL if the expression returns A, otherwise it will return the result of the expression. The outer ISNULL() will transform NULL into the empty string or return whatever non-NULL value its first argument has got.

Related

Snowflake -When value doesn't exist make sure its NULL and not empty

I have the following fb.org_story that returns some rows empty, I want to change that so instead of empty it shows NULL (without creating a file format)
select
fb.org_story as pvt_story
from prod.facebook fb
NULLIF is a little short than use a full IFF or CASE statement
SELECT
NULLIF(fb.org_story,'') AS pvt_story
FROM prod.facebook AS fb
But if the string has whitespace around it you might need to TRIM that also, thus I would be inclined to use:
SELECT
NULLIF(TRIM(fb.org_story),'') AS pvt_story
FROM prod.facebook AS fb
So, if you have NULLs and what them displayed as the text NULL we need to convert to TEXT then COALESCE,NVL,IFNULL the desired output
SELECT
fb.org_story AS pvt_story
,fb.org_story::text AS as_text
,NVL(fb.org_story::text, 'NULL') as null_says_null_a
,COALESCE(fb.org_story::text, 'NULL') as null_says_null_b
,IFNULL(fb.org_story::text, 'NULL') as null_says_null_c
,IFF(fb.org_story IS NULL, 'NULL', fb.org_story::text ) as null_says_null_d
FROM VALUES (123), (null) AS fb(org_story)
PVT_STORY
AS_TEXT
NULL_SAYS_NULL_A
NULL_SAYS_NULL_B
NULL_SAYS_NULL_C
NULL_SAYS_NULL_D
123
123
123
123
123
123
NULL
NULL
NULL
NULL
you can use coalesce() as well
select coalesce(fb.org_story,'') AS pvt_story
FROM prod.facebook AS fb
Try One of these if you have Spaces in the data:
-- If you want to return `NULL` values
SELECT NULLIF(TRIM(' '), '') + 1 AS "Test 1"; -- Returns NULL
SELECT NULLIF(TRIM(NULL), '') + 2 AS "Test 2"; -- Returns NULL
SELECT NULLIF(TRIM(''), '') + 3 AS "Test 3"; -- Returns NULL
-- If you want to return calculated values even if the field is null.
SELECT NVL(NULLIF(TRIM(' '), ''), 0) + 4 AS "Test 4"; -- Returns 4
SELECT NVL(NULLIF(TRIM(NULL), ''), 0) + 5 AS "Test 5"; -- Returns 5
SELECT NVL(NULLIF(TRIM(''), ''), 0) + 6 AS "Test 6"; -- Returns 6
Example Usage:
SELECT NULLIF(TRIM(fb.org_story), '') + 7 AS "pvt_story"
FROM prod.facebook AS fb; -- Returns NULL
SELECT NVL(NULLIF(TRIM(fb.org_story), ''), 0) + 8 AS "pvt_story"
FROM prod.facebook AS fb; -- Returns 8

CASE statement for rows not existing on joined table

I am trying to wrap the inner CASE statements below with an outer CASE statement to output '00-00-00-00-00' if there is not a matching row found on the left-joined OtherTable C , instead what is happening is when there is not a row found in OtherTable C then it is outputting ---- (just dashes).
SELECT A.INV_ITEM_ID,
CASE WHEN C.INV_ITEM_ID '' THEN '00-00-00-00-00'
ELSE ( CONCAT(CASE WHEN C.STORAGE_AREA like '[0-9]'
THEN '0'+ C.STORAGE_AREA
WHEN C.STORAGE_AREA = '' THEN '00'
ELSE C.STORAGE_AREA END ,'-', CASE WHEN C.STOR_LEVEL_1 like '[0-9]'
THEN '0' + C.STOR_LEVEL_1
WHEN C.STOR_LEVEL_1 = '' THEN '00'
ELSE C.STOR_LEVEL_1 END , '-',
CASE WHEN C.STOR_LEVEL_2 like '[0-9]'
THEN '0' + C.STOR_LEVEL_2
WHEN C.STOR_LEVEL_2 = '' THEN '00'
ELSE C.STOR_LEVEL_2 END, '-',
CASE WHEN C.STOR_LEVEL_3 like '[0-9]'
THEN '0' + C.STOR_LEVEL_3
WHEN C.STOR_LEVEL_3 = '' THEN '00'
ELSE C.STOR_LEVEL_3 END, '-',
CASE WHEN C.STOR_LEVEL_4 like '[0-9]'
THEN '0' + C.STOR_LEVEL_4
WHEN C.STOR_LEVEL_4 = '' THEN '00'
ELSE C.STOR_LEVEL_4 END ) ) END
FROM MyTable A
LEFT OUTER JOIN OtherTable C ON C.INV_ITEM_ID = A.INV_ITEM_ID
Is there a way to achieve this without having to use a Sub-query here?
If there is no match in a left join the OtherTable value will be null not ''
So when you say this:
CASE WHEN C.INV_ITEM_ID '' THEN '00-00-00-00-00'
You are checking if there is a zero length string or '' in the field c.INV_ITEM_ID
Instead you should use
CASE WHEN C.INV_ITEM_ID is null THEN '00-00-00-00-00'
You likely do not have any c.INV_ITEM_ID with string value ''. So when there is no matching data in the left join (ie the value is null) the case expression moves on and performs a concatenation. Each sub-case expression checks for c.STOR_LEVEL_1 and doesn't have a match so goes with the "else" or C.STOR_LEVEL_1. So what you actually have is
concat(null,'-',null,'-',null,'-',null,'-')
Which evaluates to ----
Might be able to cut your SQL down a bit:
SELECT
A.INV_ITEM_ID,
CONCAT(
RIGHT(CONCAT('00', C.STOR_LEVEL_1), 2), '-',
RIGHT(CONCAT('00', C.STOR_LEVEL_2), 2), '-',
RIGHT(CONCAT('00', C.STOR_LEVEL_3), 2), '-',
RIGHT(CONCAT('00', C.STOR_LEVEL_4), 2)
) as x
CONCAT behaves slightly differently to + with NULL. CONCAT treats null as emptystring, but + will nullify the whole expression. This, whether your column is null, a single digit or double digit, if you CONCAT it onto '00' then take the rightmost 2 you end up with a 2 digits number (00 if null, 0x if one digit, xx if 2).

SQL Server 2014 - Case statement not exiting

I am having trouble writing a query to meet the following requirement. One point if Cust_3_3_a through Cust_3_3_c is selected, or Cust_3_3_f through Cust_3_3_h is selected, or Cust_3_4_ is selected; Zero points if Cust_3_3_e is selected and Cust_3_4_ is not selected with value '-'. Selected essentially means a the field has a value of a, b, c, etc.
Here is my test data and query. I would expect with 'Cust_3_4_' set to '-', that 0 should return but 1 returns instead. Is SQL not exiting the case when it hits 0 since the following check would return 1? Thanks in advance.
declare #test table (QuestionKey nvarchar(100), ResponseValue nvarchar(100))
insert into #test (QuestionKey, ResponseValue)
values
('Cust_3_3_a', ''), ('Cust_3_4_', '-'),
('Cust_3_3_b', ''),
('Cust_3_3_c', ''),
('Cust_3_3_e', 'a'),
('Cust_3_3_f', ''),
('Cust_3_3_g', ''),
('Cust_3_3_h', '')
select
max(case
when (
(t.questionkey = 'Cust_3_3_e' AND nullif(t.ResponseValue, '') IS NOT NULL)
and (t.questionkey = 'Cust_3_4_' AND nullif(t.ResponseValue, '') != '-')
) then 1
when (
(t.questionkey = 'Cust_3_3_e' AND nullif(t.ResponseValue, '') IS NOT NULL)
and (t.questionkey = 'Cust_3_4_' AND nullif(t.ResponseValue, '') = '-')
) then 0
when (
t.questionkey BETWEEN 'Cust_3_3_a' AND 'Cust_3_3_c'
OR t.questionkey BETWEEN 'Cust_3_3_f' AND 'Cust_3_3_h'
OR t.questionkey = 'Cust_3_4_'
) and nullif(t.ResponseValue, '') IS NOT NULL then 1
else 0
end) as test1
from #test t
Not sure what you want but I think you are confused with how case statement works. In order for you to return 0 for Cust_3_4_ where ResponseValue != '-', you need to have an actual row with QuestionKey = Cust_3_4_ and ResponseValue != '-' in your table (which you do not have in the above data set)
Also, you have applied MAX function outside your case so it will return you the maximum value 1 if any of the case condition returns 1. If you want the final result 0, you need to use MIN instead BUT please be aware that the 0 will be returned because of the following condition on Cust_3_3_e. Cust_3_4_ will have nothing to do with the 0
declare #test table (QuestionKey nvarchar(100), ResponseValue nvarchar(100))
insert into #test (QuestionKey, ResponseValue)
values
('Cust_3_3_a', ''), ('Cust_3_4_', '-'),
('Cust_3_3_b', ''),
('Cust_3_3_c', ''),
('Cust_3_3_e', 'a'),
('Cust_3_3_f', ''),
('Cust_3_3_g', ''),
('Cust_3_3_h', '')
select * from #test
order by 1 asc
select *,case when QuestionKey IN ('Cust_3_3_a','Cust_3_3_b','Cust_3_3_c') THEN 1
when QuestionKey = 'Cust_3_3_e' THEN 0
when QuestionKey IN ('Cust_3_3_f','Cust_3_3_g','Cust_3_3_h') THEN 1
when QuestionKey = 'Cust_3_4_' AND ResponseValue = '-' THEN 1
when QuestionKey = 'Cust_3_4_' AND ResponseValue <> '-' THEN 0
end test1
from #test

SQL combine columns strings

I have an sql table that looks like the following
p1 c1 c2 c3 c4 c5 c6 c7
A B C D E F NULL NULL
A B C NULL NULL NULL NULL NULL
A B NULL NULL NULL NULL NULL NULL
A NULL NULL NULL NULL NULL NULL NULL
i need a select sql query with 1 column and the output to look like
Result
A > B > C > D > E > F
A > B > C
A
i tried nested select case however i am getting only nulls
select
case when x.p1 IS not NULL then(
x.p1 + case when x.c1 IS not NULL then(
' > '+ x.c1 + case when x.c2 IS not NULL then(
' > '+ x.c2 + case when x.c3 IS not NULL then(
' > '+ x.c3 + case when x.c4 IS not NULL then(
' > '+ x.c4 + case when x.c5 IS not NULL then(
' > '+ x.c5 + case when x.c6 IS not NULL then(
' > '+ x.c6 + case when x.c7 IS not NULL then(
' > '+ x.c7 )end )end )end )end )end )end )end) end as tree
from mytable
is there a better way to get the result i want?
what is wrong with my select case?
Based on the fact that in TSQL 'a string' + null equals null, you can simplify the query to this:
select
p1
+ isnull(('>' + c1), '')
+ isnull(('>' + c2), '')
+ isnull(('>' + c3), '')
+ isnull(('>' + c4), '')
+ isnull(('>' + c5), '')
+ isnull(('>' + c6), '')
+ isnull(('>' + c7), '')
from mytable
SQLFiddle link: http://www.sqlfiddle.com/#!3/02b05/8
what is wrong with my select case?
You are using the table alias x which appears to not be defined anywhere.
I made your query work in two steps:
define the x table alias. For that, simply write mytable x at the end instead of just mytable
after the above fix, it'll still return null, because the case statements only have one branch and when the condition is not met they still return null. To fix that, replace every end with else '' end (to return an empty string rather than a null)
Here's your version working: http://www.sqlfiddle.com/#!3/02b05/11

concatenate two database columns into one resultset column

I use the following SQL to concatenate several database columns from one table into one column in the result set:
SELECT (field1 + '' + field2 + '' + field3) FROM table1
When one of the fields is null I got null result for the whole concatenation expression. How can I overcome this?
The database is MS SQL Server 2008. By the way, is this the best way to concatenate database columns? Is there any standard SQL doing this?
The SQL standard way of doing this would be:
SELECT COALESCE(field1, '') || COALESCE(field2, '') || COALESCE(field3, '') FROM table1
Example:
INSERT INTO table1 VALUES ('hello', null, 'world');
SELECT COALESCE(field1, '') || COALESCE(field2, '') || COALESCE(field3, '') FROM table1;
helloworld
If you were using SQL 2012 or above you could use the CONCAT function:
SELECT CONCAT(field1, field2, field3) FROM table1
NULL fields won't break your concatenation.
#bummi - Thanks for the comment - edited my answer to correspond to it.
Normal behaviour with NULL is that any operation including a NULL yields a NULL...
- 9 * NULL = NULL
- NULL + '' = NULL
- etc
To overcome this use ISNULL or COALESCE to replace any instances of NULL with something else..
SELECT (ISNULL(field1,'') + '' + ISNULL(field2,'') + '' + ISNULL(field3,'')) FROM table1
If you are having a problem with NULL values, use the COALESCE function to replace the NULL with the value of your choice. Your query would then look like this:
SELECT (COALESCE(field1, '') + '' + COALESCE(field2, '') + '' + COALESCE(field3,'')) FROM table1
http://www.codeproject.com/KB/database/DataCrunching.aspx
Use ISNULL to overcome it.
Example:
SELECT (ISNULL(field1, '') + '' + ISNULL(field2, '')+ '' + ISNULL(field3, '')) FROM table1
This will then replace your NULL content with an empty string which will preserve the concatentation operation from evaluating as an overall NULL result.
If both Column are numeric Then Use This code
Just Cast Column As Varchar(Size)
Example:
Select (Cast(Col1 as Varchar(20)) + '-' + Cast(Col2 as Varchar(20))) As Col3 from Table
Just Cast Column As Varchar(Size)
If both Column are numeric then use code below.
Example:
Select (Cast(Col1 as Varchar(20)) + '-' + Cast(Col2 as Varchar(20))) As Col3 from Table
What will be the size of col3 it will be 40 or something else