Change column being used in WHERE condition based on IF condition - sql

I apologize for the title - i was struggling coming up with something better.
Been doing some research on this and did find some close examples, however this is not quite what i need.
Basically i have a table with two columns that i want to evaluate under certain conditions. Column 1 is a identifier that can also be null. Column 2 is a SessionId that can change also.
Primarily i key off of column1, but when column1 is null i would like to key off of column2 instead. The example i linked above doesn't change the column being evaluated in the WHERE clause, only the value being used to evaluate the clause.
Here is some pseudo code to illustrate what i am trying to do:
SELECT * FROM MyTable
WHERE
IF Column1 NOT NULL
Column1 = #myvariable1
ELSE
Column2 LIKE '%' + #myvariable2 + '%'
Is something like this even possible? Can i switch the column to be evaluated in the WHERE clause based on the value of one of the columns?
I hope all that makes sense.
TIA

You could use CASE:
SELECT *
FROM MyTable
WHERE (CASE WHEN Column1 IS NOT NULL AND Column1 = #myvariable1 THEN 1
WHEN Column2 LIKE '%' + #myvariable2 + '%' THEN 1
ELSE 0
END) = 1;

You should check for nullable on Column1 on both validation of the where clause in case you set #myvariable1 to null.
SELECT * FROM MyTable
WHERE (Column1 IS NOT NULL AND Column1 = #myvariable1)
OR (Column1 IS NULL and Column2 LIKE '%' + #myvariable2 + '%')

WHERE Column1 = #myvariable1
OR ( Column1 IS NULL AND Column2 LIKE '%' + #myvariable2 + '%' )

Related

What do the quotes mean in this SQL Server snippet? (SELECT '' column1, '' column 2)

I'd like to know the purpose of the two single quotes in front of each column. This is in a stored procedure. Thank you for your help!
INSERT INTO #temptable1
SELECT DISTINCT '' column1
,column2
,'' column3
,'' column4
FROM table1
WHERE column1 NOT LIKE 'string1%'
AND column2 <> 'string2'
AND column3 <> 'string3'
The expression '' is an empty string. So this is using an empty string instead of NULL for "missing" values.
I would write this code as:
SELECT DISTINCT '' as column1, column2, '' as column3, '' as column4
This might make it clearer. I always use as for column aliases -- so it is easier to spot missing commas (there should always be an as for a column alias).
More commonly, this would probably just use default values (which are usually NULL but could be ''):
INSERT INTO #temptable1 (column2)
SELECT DISTINCT column2
FROM table1
WHERE column1 NOT LIKE 'string1%'
AND column2 <> 'string2'
AND column3 <> 'string3';

sql case condition as SELECT from another table

I have a working procedure with case conditions. It gets triggered on every INSERT and checks for specific values in one column then updates another column. The entire SP has between 20-30 CASE conditions.
I'm moving from MySQL to PostgreSQL and was wondering if it is possible to automate it and have SELECT inside CASE? (see code below)
SELECT col1,col2 FORM myCASEtbl
ABC | 1
DEF | 2
123 | 3
FROM THIS:
UPDATE myTable
SET columnName = CASE
WHEN OtherColumn LIKE '%ABC%' THEN columnName = 1
WHEN OtherColumn LIKE '%DEF%' THEN columnName = 2
WHEN OtherColumn LIKE '%123%' THEN columnName = 4
...
ELSE columnName
END
WHERE columnName IS NULL;
TO THIS:
UPDATE myTable
SET columnName = CASE
SELECT 'WHEN OtherColumn LIKE ' + col1 + ' THEN columnName = ' + col2 FROM myCASEtbl
ELSE columnName
END
WHERE columnName IS NULL
Yes, you can use a subquery:
UPDATE myTable
SET columnName = (SELECT ct.col2
FROM myCaseTable ct
WHERE mytable.OtherColumn like '%' || ct.col || '%'
LIMIT 1
)
WHERE columnName IS NULL;
The LIMIT is a convenient way to guarantee that the subquery returns one row.

How to create Dynamic SQL based on two tables

I'm trying to construct a dynamic SQL based on the Cartesian product of two tables
Table1 Colunm1 Dev Test
table2 Column2 ProductNumber ProductDesc
here the result that I want:
(ProductNumber LIKE '%dev%' OR ProductDesc LIKE '%dev%' )
AND (ProductNumber LIKE '%Test%' OR ProductDesc LIKE '%Test%')
I tried to do some simple query like below but I cannot manage to add a AND instaed a OR between each column1 value
SELECT #sql = COALESCE(#sql + Colunm2 + ' LIKE ''%' + Colunm1 + '%'' OR ','')
from Table1, Table2
that give:
ProductNumber LIKE '%dev%' OR
ProductDesc LIKE '%dev%' OR
ProductNumber LIKE '%Test%' OR
ProductDesc LIKE '%Test%'
I can do it with a while but if you have a better solution I can use it
I note that you want your ORs grouped by table1.column1, so the below should work:
SELECT CASE WHEN row_num = 1 THEN ') AND (' ELSE '' END || code as code
FROM (
SELECT Column1, ROW_NUMBER() OVER (GROUP BY Column 1) as row_num, COALESCE( Column2 + ' LIKE ''%' + Column1 + '%'' OR ','') as code
FROM Table1, Table2
) gen_code
ORDER BY Column1, row_num
(I haven't tested it, but I have written lots of such code before)
It adds an additional ') AND (' at the beginning, but you can get it away if you use another ROW_NUMBER over the whole thing. It also lacks a closing ')', but you get the idea. Other than that, use your current approach with a variant of above code. Note that I assumed you have no string aggregation function available.

Computed columns with null

I am creating a view (using MS sql 2008) with creates a calculated field as a COLUMN1 + COLUMN2. Everything is fine and dandy but: Both COLUMN1 and COLUMN2 can be NULL.
I want to follow the following rule:
2 + 2 = 4
2 + NULL = 2
NULL + 2 = 2
0 + 0 = 0
NULL + NULL = NULL
If I use ISNULL(column2, 0), then all the rules will be followed but not the last one.
How do I need to create the view
CREATE VIEW dbo.test
AS
SELECT COLUMN1, COLUMN2, (????????) AS CALCULATEDCOL FROM dbo.TabTest;
GO
create view dbo.test AS
select
column1,
column2,
case
when column1 is null and column2 is null then null
-- or when isnull(column1, column2) is null then null
else isnull(column1, 0) + isnull(column2, 0)
end as CALCULATEDCOL
from dbo.TabTest
CASE
WHEN COALESCE(COLUMN1, COLUMN2) IS NULL THEN NULL
ELSE ISNULL(COLUMN1, 0) + ISNULL(COLUMN2, 0)
END
You can do this without a case statement:
select coalesce(column1+column2,
coalesce(column1, 0) + column2,
column1 + coalesce(column2, 0)
)
(The function coalesce is equivalent to isnull, except coalesce is standard SQL and can take more than two arguments.)
There is no disadvantage to using the case statement. I'm just offering this as an alternative.
Use CASE expression instead. Like so:
CREATE VIEW dbo.test AS
SELECT
COLUMN1,
COLUMN2,
CASE
WHEN COLUMN1 IS NULL AND COLUMN2 IS NULL THEN NULL
WHEN COLUMN1 IS NULL THEN 0 + COLUMN2
WHEN COLUMN2 IS NULL THEN 0 + COLUMN1
ELSE COLUMN1 + COLUMN2
END AS CALCULATEDCOL
FROM dbo.TabTest;
GO
it is more simple than people would expect, using CASE for this question is a waste when there is a standard function called COALESCE, just replace your questionmarks with this:
COALESCE(col1 + col2, col1, col2)
You rule seems to be "Treat nulls as zero unless both fields are null, in which case, return null." I would approach this with a case, to separate the two rules:
CASE WHEN column1 is null and column2 is null then null
ELSE ISNULL(column1,0) + ISNULL(column2,0)
END
You can use a CASE to handle the last condition:
CREATE VIEW dbo.test
AS
SELECT column1,
column2,
CASE
WHEN column1 IS NULL
THEN column2 + 0
WHEN column2 IS NULL
THEN column1 + 0
WHEN column1 IS NOT NULL AND column2 IS NOT NULL
THEN column1 + column2
ELSE NULL
END AS calculatedcol
FROM dbo.tabtest;
Using a case system, you can handle when both values are null from when either of them is NULL
CREATE VIEW dbo.test
AS
SELECT COLUMN1, COLUMN2,
CASE WHEN (COLUMN1 IS NULL AND COLUMN2 IS NULL) THEN NULL
ELSE ISNULL(COLUMN1,0)+ISNULL(COLUMN2,0)
END AS CALCULATEDCOL
FROM dbo.TabTest;
GO
You can use the case keyword to achieve this.
Something on these lines
SELECT CASE
WHEN COLUMN1 IS NULL AND COLUMN2 IS NULL THEN NULL
WHEN COLUMN1 IS NULL AND... etc...

Update column if another column contains a string

I have a table that contains three columns.
column1 column2 column3
mytestdata test
myotherdata test
I want to insert 'somestring' into column3 if column1 contains the value in column2
The result would look like:
column1 column2 column3
mytestdata test 'somestring'
myotherdata test
SQL Server:
UPDATE myTable
SET column3 = 'somestring'
WHERE column1 LIKE '%' + column2 + '%'
SQL Server:
UPDATE theTable SET column3 = 'somestring'
WHERE CHARINDEX (column2, column1) > 0
You have several options, depending on the RDBMS.
For both MySQL and Oracle:
UPDATE yourTable
set column3 = 'somestring'
where INSTR(column2, column1) > 0
For SQL Server:
UPDATE yourTable
set column3 = 'somestring'
where CHARINDEX(column1, column2) > 0
You could do something like below
UPDATE tmp
SET
column3 = (CASE WHEN tmp.column1 like '%' + tmp.column2 + '%' THEN 'something' ELSE tmp.column3')
FROM
tablename tmp