SQL - Select only one value from multiple fields - sql

Assume the following
col1 col2 col3 col4
------+----------+---------+---------
abc | | |
Yes, col1-4 have a space in them!
I want to select the column that is not a space . On row 1 it's col1, but on row 20 it may be col3, row 55 it may be col2, and so on. I need to return just that column.
There will always be only one column with a stored value within this range of four columns, I just need the one that actually has information in it.
This will be part of a greater query for a report, so regardless of what column abc is in I need that to look the same in every result case. Meaning I can't have the results be col1 for one case and col2 for the other because the report won't recognize. The column needs to always be called the same.
Yes, I know it's better to store NULLS versus spaces and why use four columns when only one can have data, why not use one. I've complained enougth about that so don't rip me a new one about bad db design because I AGREE.

SELECT LTRIM(RTRIM(col1 + col2 + col3 + col4))
Here we go... Why not add bad code to bad design. You could technically add all of the columns together and then trim them for leading/trailing spaces. I don't recommend it for performance on large scale deployments. Heck, I don't recommend this for any production script but I've been here before... Gotta do what you can to get it done.

Why not use a CASE statement, like
CASE WHEN col1 <> ' ' THEN col1
WHEN col2 <> ' ' THEN col2
WHEN col3 <> ' ' THEN col3
WHEN col4 <> ' ' THEN col4
END

You can do this:
case
when col1 != '' then col1
when col2 != '' then col2
...
end

Related

Google Spreadsheet When converting the GoogleFinance currency returned value only from the first line

In Google Spreadsheet the column "B" three rows with prices in $, but when converting the currency returned value only from the first line, please tell me where the error?
=QUERY(importXML("https://www.globalpetrolprices.com/Azerbaijan/", "//*[#id='graphPageLeft']/table[1]//tr"),
"Select Col4
label Col4 ''
format Col4 '0.00'")
* GOOGLEFINANCE("currency:USDEUR")
I was advised this solution:
=ArrayFormula(TEXT(QUERY(ARRAY_CONSTRAIN(importXML("https://www.globalpetrolprices.com/Azerbaijan/", "//*[#id='graphPageLeft']/table[1]//tr"), 4, 4), "Select Col4 label Col4 ''") * GOOGLEFINANCE("currency:USDEUR"),"€ 0.00"))

How can I use consecutive conditional clause in SQL?

I was trying to work with CASE WHEN in Postgresql in order to evaluate something and then do another thing. However, I need not only to check two things but they must be checked in consecutive order.
Example, let's say I have 3 columns: col1, col2 and col3.
I want to check first if col1 is greater than 0. After checking this I want to check if col2 is greater than 0. If that's the case, I will create another column which will be the sum of all of them. However, I can't do this:
select case when col1>0 and col2>0 then col1+col2+col3 end as...
I need to do something like this:
select case when col1>0 then (case when col2>0 then col1+col2+col3) else NULL end as...
But that doesn't work. So, what can I do?
You were close. You can do:
select
case when col1 > 0 then case when col2 > 0 then col1 + col2 + col3 end
else NULL end as my_column1
You had missed the inner end.
By the way, a CASE expression evaluates to NULL when no when clause is matched. Therefore, else NULL is redundant.

SQL - Combine two strings having the second string always right aligned

I'm currently trying to attain alignment via SQL queries when combining two columns.
my current data set looks something like:
Col1 Col2
usd US Dollar
cad Canadian Dollar
mxn Mexican Peso
And I want to combine col1 + col2, but no matter how many characters are in col2, the data that comes out of col1 needs to always be aligned to the right in the display.
The display is limited at 49 characters. Col2 has no specific limit as it's a description column, while col1 is a percentage column so it will have a maximum of 7 characters: 100.00%
Any help will be appreciated.
Thanks
If I understood your question well and assuming that col1 has maximal length of 7 characters while col2 length is undetermined, the following query should give you the results needed:
SELECT
ISNULL(myTable.col1, '')
+ (CASE WHEN LEN(ISNULL(myTable.col2, '')) < 49 - LEN(ISNULL(myTable.col1, ''))
THEN SPACE(49 - LEN(ISNULL(myTable.col1, '')) - LEN(ISNULL(myTable.col2, '')))
+ ISNULL(myTable.col2, '')
ELSE ' ' + LEFT(ISNULL(myTable.col2, ''),
49 - LEN(ISNULL(myTable.col1, '')) - 1)
END) AS cols_for_49chars_display
FROM
myTable
Since col1 is assumed to have max length of 7 characters, the CASE statement verifies the length of col2 for specific row.
If it's lower than 49 - LEN(col1), prepend col2 with 49 - LEN(col1) - LEN(col2) spaces using TSQL SPACE function (docs here) to right-align col2 and then add col2 itself.
In opposite case add one space after col1 and left-cut col2 to the length of 49 - LEN(ISNULL(myTable.col1, '')) - 1 when 1 being the length of the added single space character.
Example input data and results of the query:
Lets take as an example the data provided in your answer adding an extra row to show what will happen when col2 value is too long:
myTable contents:
col1 col2
------------------------------------------------------------------------------------------------
usd US Dollar
cad PCanadian Dollar
mxn Mexican Peso
dummy Very long description of a "dummy" currency that in fact doesn't exist in the real world
The result of the query on above rows would be:
cols_for_49chars_display
-------------------------------------------------
usd US Dollar
cad PCanadian Dollar
mxn Mexican Peso
dummy Very long description of a "dummy" currency
I hope it helps at least slightly.

Fastest T-SQL to convert zeros to NULL in multiple columns

We have some large data warehouse tables. Our transformation code makes sure all the numeric measure columns use zero instead of NULL for T-SQL math.
(CASE WHEN NULL or '' then 0)
In the last transformation section we need to turn all the zeros back to NULL for use in Analysis Services MDX. Trying to make sure the No Data lines are not showing in the reports. Previously set to 0 for SQL math because 1 + NULL = NULL in SQL and we want it to equal 1
where as 1 + NULL in Analysis Services = 1.
It is taking about two hours to do the back conversion with individual set statements for each column/measure. I am looking for a way to do it in one read through the table/file instead of thirty-three table scans.
Will the following work and will it be faster?
UPDATE MyTable
SET Col1 = NULLIF(Col1, 0),
Col2 = NULLIF(Col2, 0),
Col3 = NULLIF(Col3, 0)
WHERE (Col1 = 0
OR Col2 = 0
OR Col3 = 0)
How do you know that it will not be fast enough? did you do any bench marking? You can as well use CASE condition like below but per MSDN Spec both are same. Which states that:
NULLIF is equivalent to a searched CASE expression in which the two
expressions are equal and the resulting expression is NULL.
UPDATE MyTable
SET Col1 = CASE WHEN Col1 = 0 THEN NULL END,
Col2 = CASE WHEN Col2 = 0 THEN NULL END,
Col3 = CASE WHEN Col3 = 0 THEN NULL END
WHERE (Col1 = 0 OR Col2 = 0 OR Col3 = 0)

SQL split in one column into two columns based on delimiter(s)

My data in one column(col) is as follows:
Col
Accounts::Changes
Applications::Zen::Other
Server::Access
I need this data to go to two columns. I want the first string before the delimiter (:) to go into one column (col1) and the last string after the last delimiter to go into another column (col2).
The output should be:
Col1 Col2
Accounts Changes
Applications Zen
Server Access
I am using sql server 2008 R2
You should be able to do this with basic string operations:
select left(col, charindex('::', col) - 1) as col1,
right(col, charindex('::', reverse(col)) - 1) as col2
from table t;
Here is a SQL Fiddle.
I have been able to achieve this as follows:
select A.Col1,
case when CHARINDEX('::',A.Colx)>0
then SUBSTRING(A.Colx,1,CHARINDEX('::',A.Colx)-1)
else A.Colx end Col2,
CASE WHEN CHARINDEX('::',A.Colx)>0
THEN SUBSTRING(A.Colx,CHARINDEX('::',A.Colx)+2,len(A.Colx))
ELSE NULL END as Colx3
FROM (
select
case when CHARINDEX('::',Col)>0
then SUBSTRING(Col,1,CHARINDEX('::',Col)-1)
else Col end Col1,
CASE WHEN CHARINDEX('::',Col)>0
THEN SUBSTRING(Col,CHARINDEX('::',Col)+2,len(Col))
ELSE NULL END as Colx
FROM Table1 ) as A
Although I end up getting a third column with the leftover string, I won't use it.