SQL Server Case expression conditions - sql

I am currently working on a data flow and have been given a specific requirement that i am trying to complete.
In my table I have a column which is partially NULL due to a couple of reasons.
What I'm trying to do is write a case expression within my select statement that has two conditions:
When NULL use a different value from another column (which is pulled from another table using a join)
If the column is still NULL (in both cases) then use a different value from another column in the table which will ensure the column is populated.
So basically, if it's NULL do this, if its still NULL, then do this which will mean my column is populated as i intend.
I've been playing around but have been unable to produce the required result. Is this something that can be achieved using a CASE expression ?
Any help/advice would be appreciated.
Thanks.

You are describing the coalesce() function:
coalesce(col1, col2, col3)
You can use this in either a select or update.

Related

How to avoid a column if it contains null without mentioning its name

How to avoid a column if it contains null without mentioning its name
select * from
ExmGp a
inner join
ExmMstr b
on a.ETID = b.EID
inner join
ExmMrkntry c
on b.AcYear = c.Acyear
I am trying to join three different tables like the above code but in result some of the columns are null. is it possible to avoid them using where condition?
thanks in advance
No, but it is important that you understand the reason why.
The WHERE clause filters rows out of the result set not columns. So, what you are asking is not supported by WHERE or anything else.
Importantly, a SQL query returns data in a tabular format. This format specifies the columns in the result set. These columns cannot be dynamic; they are fixed for the query (unless you construct a string to execute the query).
So, you are "stuck" with all the columns specified in the SELECT. I would recommend that you list each of the columns that you want rather than using SELECT *.
No there is no built-in language construct in TSQL to directly check for NULLs anywhere in the row. There are a number of workarounds though.
See this question for possible solutions
How to count in SQL all fields with null values in one record?

Return Oracle SQL Columns that doesnt have null value [duplicate]

I have 20 columns in my table....
How can I select only columns that don't have null value
col1 col2 col3
20 12 null
Desired output
col1 col2
20 12
The semantics of SQL don't allow this - every SQL query includes a projection, by which you specify what columns you want in the output.
Unless you run the query twice, you can't know ahead of time what the results will be. In fact, even if you run the query twice, the results may change in between (unless you run it in serializable mode).
In other words, the question doesn't make a lot of sense.
On the other hand, if your requirement is to simply hide the column when displayed to the user, that's an entirely different question - one for which the answer does not lie in SQL, but in your presentation logic.
You can go to the table's metadata and check for the columns which are defined NOT NULL and create a select query with only those columns.

Which is better with respect to database performance?

We are expecting null values in a particular column. We would like to capture them in the output also. There are two possible values other than null. They are WE and EA. So, out of these two syntax given below, which one performs better?
…( "Src_Dtl"."REGN" not in ('WE','EA') or
"Src_Dtl"."REGN" is null)…
or
...(coalesce(CVRG_REGN, ‘WE’))...
Thanks in advance.
Null values always returns false for comparisons so not in ('a','b') a null comparison would return false so it would not be included. We are forced to add a 2nd clause or something is null. This is two operations on the data.
The coalesce function says give me the first non null value in the list. It is one operation (check if the value is null) and has two possible outcomes. Because this is one operation it is faster than doing two operations.

How to do damage with SQL by adding to the end of a statement?

Perhaps I am not creative or knowledgeable enough with SQL... but it looks like there is no way to do a DROP TABLE or DELETE FROM within a SELECT without the ability to start a new statement.
Basically, we have a situation where our codebase has some gigantic, "less-than-robust" SQL generation component that never uses prepared statements and we now have an API that interacts with this legacy component.
Right now we can modify a query by appending to the end of it, but have been unable to insert any semicolons. Thus, we can do something like this:
/query?[...]&location_ids=loc1')%20or%20L1.ID%20in%20('loc2
which will result in this
SELECT...WHERE L1.PARENT_ID='1' and L1.ID IN ('loc1') or L1.ID in ('loc2');...
This is just one example.
Basically we can append pretty much anything to the end of any/most generated SQL queries, less adding a semicolon.
Any ideas on how this could potentially do some damage? Can you add something to the end of a SQL query that deletes from or drops tables? Or create a query so absurd that it takes up all CPU and never completes?
You said that this:
/query?[...]&location_ids=loc1')%20or%20L1.ID%20in%20('loc2
will result in this:
SELECT...WHERE L1.PARENT_ID='1' and L1.ID IN ('loc1') or L1.ID in ('loc2');
so it looks like this:
/query?[...]&location_ids=');DROP%20TABLE users;--
will result in this:
SELECT...WHERE L1.PARENT_ID='1' and L1.ID IN ('');DROP TABLE users;--');
which is a SELECT, a DROP and a comment.
If it’s not possible to inject another statement, you limited to the existing statement and its abilities.
Like in this case, if you are limited to SELECT and you know where the injection happens, have a look at PostgreSQL’s SELECT syntax to see what your options are. Since you’re injecting into the WHERE clause, you can only inject additional conditions or other clauses that are allowed after the WHERE clause.
If the result of the SELECT is returned back to the user, you may want to add your own SELECT with a UNION operation. However, PostgreSQL requires compatible data types for corresponding columns:
The two SELECT statements that represent the direct operands of the UNION must produce the same number of columns, and corresponding columns must be of compatible data types.
So you would need to know the number and data types of the columns of the original SELECT first.
The number of columns can be detected with the ORDER BY clause by specifying the column number like ORDER BY 3, which would order the result by the values of the third column. If the specified column does not exist, the query will fail.
Now after determining the number of columns, you can inject a UNION SELECT with the appropriate number of columns with an null value for each column of your UNION SELECT:
loc1') UNION SELECT null,null,null,null,null --
Now you determine the types of each column by using a different value for each column one by one. If the types of a column are incompatible, you may an error that hints the expected data type like:
ERROR: invalid input syntax for integer
ERROR: UNION types text and integer cannot be matched
After you have determined enough column types (one column may be sufficient when it’s one that is presented the user), you can change your SELECT to select whatever you want.

SQL Select between two fields depending on the value of one field

I am using a PostgreSQL database, and in a table representing some measurements I've two columns: measurement, and interpolated. In the first I've the observation (measurement), and in the second the interpolated value depending on nearby values. Every record with an original value has also an interpolated value. However, there are a lot of records without "original" observations (NULL), hence the values are interpolated and stored in the second column. So basically there are just two cases in the database:
Value Value
NULL Value
Of course, it is preferable to use the value from the first column if available, hence I need to build a query to select the data from the first column, and if not available (NULL), then the database returns the value from the second column for the record in question. I have no idea how to build the SQL query.
Please help. Thanks.
You can use Coalesce:
The COALESCE function returns the first of its arguments that is not null. Null is returned only if all arguments are null.
Select Coalesce( first_value, second_value )
From your_table
This would return first_value if it is not NULL, second_value otherwise.
Peter nailed it. But for the sake of completeness (the title of your question is more general than your particular issue), here goes the docs for the several conditional expressions available in Postgresql (and in several other databases) : CASE, COALESCE, NULLIF, GREATEST, LEAST. The first one is the most general.