Cast string as "Column Reference" in HIVE SQL - sql

I have a query that is meant to use bind values to retrieve information from a table and test if any field is NULL. The user enters a column name for the bind value and that column is then tested for any NULL values. Here is a simplified version of the query:
SELECT
CASE
WHEN ISNULL(bind.value)
THEN 'PASS'
ELSE 'FAIL'
END AS Solution
This keeps returning 'FAIL' I think because ISNULL() is testing the column entered as a string. Instead, I need it to test the fields in the column, rather than the string holding the column's name. Is there anyway to cast this string as a reference or pointer (I know SQL doesn't have pointer but a pointer-like object) to the a column?
NOTE: When I replace bind.value with the column name it returns 'PASS.' I'm really trying keep this as dynamic as possible so can utilize it with other tables without having to write a new query for each table I use this on.

Most probably you are passing empty strings instead of NULL.
empty string '' is not the same as NULL in Hive, add test for empty string:
SELECT
CASE
WHEN ISNULL(bind.value) OR cast(bind.value as string)='' THEN 'PASS'
ELSE 'FAIL'
END AS Solution

Related

Need to fetch Boolean type column as varchar from source table and store as varchar in target table in Amazon redshift

I have been working with redshift for a month. I need your help regarding this;
I need to create a target table using source table (create table target as select * from source), there is a column in source table type of boolean, I need to store that column as varchar in target table. Tried lots of methods like cast, convert..etc nothing worked for me. After done with lots of search, I got to know that boolean cannot be converted to another data type in redshift.
It shows me below error;
Amazon Invalid operation: column "indicator" is of
type boolean but expression is of type character varying; [SQL
State=42804, DB Errorcode=500310] 1 statement failed.
I shall be grateful for your help.
The following approach might work for your case.
When loading the data from source table, instead of selecting all the columns using SELECT *, you explicitly call out the individual columns and for the boolean column use a case expression and evaluate the actual data and return the result as string 'true' or 'false'.
create table target as select colA, colB, case boolColC when true then 'true' else 'false' end from source
If you can't convert directly from Boolean to varchar, you could use
CASE
WHEN boolCol= TRUE THEN 'True'
WHEN boolCol= FALSE THEN 'False'
ELSE 'Unknown'
END AS boolCol
to sidestep the need for conversion.
I am able to resolve the issue using nested case statement at the time of table creation - I am posting the solution here so that It can be helpful for others as well.
case
when name in ('a', 'b') then
case offline_crt when true then 'true' else 'false' end
else 'N/A'
end as indicator
The same issue I was also facing ,please check below how I fixed it.
In my original code one column having Boolean data type and when I was doing union of two table it was failing due to below error.
[Amazon](500310) Invalid operation: UNION types character varying and boolean cannot be matched;
I have attached the screenshot for your reference:
Now I have just used the case statement inside the select for the Boolean data type column and it's working fine.

Placing a predefined value in the empty fields of an SQL query result

I need to manipulate the data that a certain SQL query outputs as a result, only by modifying the original query. Since it is s Select-Where-From query, as a novice in SQL I assume I can simply nest it inside another query of this type, resulting in a structure similar to: Select-Where-(Select-Where-From).
The data manipulation simply requires the replacement of all empty fields in a certain column (that was taken from the result of the original query) with a specific predefined value. Here are the two attempts I've made - based on findings from this website - which failed:
select NAME_OF_COLUMN, COALESCE(NULLIF(NAME_OF_COLUMN,''), 'Value_to_insert')
from
(THIS IS WHERE THE ORIGINAL SELECT QUERY GOES)
This one doesn't throw an error, but nonetheless produces empty fields instead of populating them with the value above, as if only the original query was run.
The 2nd:
Select *, NAME_OF_COLUMN=
CASE WHEN NAME_OF_COLUMN IS NULL THEN 'Value_to_insert'
WHEN NAME_OF_COLUMN='' THEN 'Value_to_insert'
ELSE NAME_OF_COLUMN
END
from
(THIS IS WHERE THE ORIGINAL SELECT QUERY GOES)
This one throws the following error (forgive me for the messy presentation, but it was not up to me):
java.sql.SQLSyntaxErrorException: ORA-00923: FROM keyword not found where expected
, org.eclipse.birt.report.engine.api.EngineException: Invalid bound column name: CREATOR_USER_NAME., org.eclipse.birt.report.engine.api.EngineException: Cannot get the result set metadata.
org.eclipse.birt.report.data.oda.jdbc.JDBCException: SQL statement does not return a ResultSet object.
SQL error #1:ORA-00923: FROM keyword not found where expected;
Can you please assist me and tell me what am I doing wrong? Perhaps I need to select a specific column and/or use the 'as' command?
Edit: I have attempted replacing the original select which was:
select table.column as NAME_OF_COLUMN
with this:
select nvl(table.column, 'Value_to_insert') as NAME_OF_COLUMN
Unfortunately, just like the first attempt, the output is identical to the output of the original query..
NAME_OF_COLUMN=CASE ... END is invalid in Oracle. You can't assign a column value in (standard) SQL like that.
If you are trying to come up with a column alias: that needs to go after the expression:
CASE
WHEN name_of_column IS NULL THEN 'Value_to_insert'
WHEN name_of_column = '' THEN 'Value_to_insert'
ELSE name_of_column
END as name_of_column
In Oracle an empty String '' is converted to NULL when you store the value. So the second condition of your CASE expression will never be true. The whole thing can be simplified to:
coalesce(name_of_column, 'Value_to_insert') as name_of_column
Note that you need to get rid of the select * part and explicitly list all other columns excluding name_of_column there, otherwise your query ends up with two columns with the same name.

SQL DB2 Replace value in a column

I have the following column, B represents boolean and the rest are empty values. I have to change all the values in this column to the word COLUMN A.
COLUMN
-----
B
I have tried different things, for example
SELECT COLUMN
FROM TABLE
WHERE COALESCE(NULLIF(COLUMN,''), 'COLUMN A');
And I receive the error: "Invalid character found in a character string argument of the function "BOOLEAN"." I'm kind of stuck to this question and I'm getting confused with this boolean value. I will be really happy if someone can help me, thanks!
The easiest thing is to use CASE expression. I am not familiar in db2, so you may want to research it further, but in other DBMSs it works like this:
SELECT CASE
WHEN COLUMN = '' THEN 'COLUMN A' -- if COLUMN = '', replace it with 'COLUMN A'
ELSE COLUMN -- otherwise, keep COLUMN as is.
END as 'COLUMN' -- name the column in the result 'COLUMN'
FROM TABLE
This is an article that explains how it works in db2:
https://www.ibm.com/support/knowledgecenter/en/SSEPEK_11.0.0/sqlref/src/tpc/db2z_caseexpression.html
The WHERE clause is unfinished. Compare the COALESCEd value to something:
SELECT COLUMN
FROM TABLE
WHERE COALESCE(NULLIF(COLUMN,''), 'COLUMN A') = 'COLUMN A';
Or better:
SELECT COLUMN
FROM TABLE
WHERE COLUMN IS NULL OR COLUMN = ''
Doesn't require any thinking/calculating to work out your selection logic. More maintainable, nicer for peer developers
*The above is generic advice for usual cases NOT involving boolean datatypes (which typically require some different treatment)
Now, you say you have to change the value to something. That requires an UPDATE statement. If this column is a boolean then it won't have a value of empty string. The blanks will be nulls:
UPDATE TABLE SET COLUMN = (some boolean) WHERE COLUMN IS NULL
If you don't want to permanently change the table data to something, but instead want to select it out as some value where a blank occurs, but keep the blanks stored in the table:
SELECT COALESCE(column, (some boolean)) FROM TABLE
Might be worth noting that not all versions of DB2 can return a boolean in a result set - this is quite typical of database vendors. Convert the boolean to something else representable using a case when, if your DB2 version is thus restricted
SELECT CASE WHEN column = TRUE THEN 'true' ELSE 'false' END FROM TABLE

SQL CASE with Alias

I am trying to change a column name based on the results of a case statement, is this possible and how would I do it...here is what I have so far but I am not good enough at SQL yet.
I want the change the column name of VALUE to become NUMVALUE if the data is numeric and ALNVALUE if the data isn't numeric. Essentially making a three column datatable a four column datatable. Is this possible?
CASE WHEN ISNUMERIC([Value])=1 THEN SELECT [VALUE] AS [NUMVALUE] ELSE SELECT [VALUE] AS [ALNVALUE] END
No, it isn't possible.
Think about the issues you'd run into when you try and use the result set. Anytime you tried to access the data, you would get an exception stating that the column couldn't be found or similar.
Dim data = Results["ColumnName"] would become unreliable.
You will need to make a separate column for each of them or put them all under the same name.
You need two CASEs = two columns:
SELECT
CASE WHEN ISNUMERIC([Value])= 1 THEN [VALUE] END AS [NUMVALUE],
CASE WHEN ISNUMERIC([Value])<>1 THEN [VALUE] END AS [ALNVALUE],
...
FROM myTable

Only want a Concatenation to appear when the value is not null

I have built a concatenation using SQL (Oracle), but I only want the concatenation to output when the value in the field is not null. I'm effectively building a website URL in the field, but in some cases the link is not yet available, but the concatenation still outputs the prefix (http://www.). If the value is null, then it should output null. At the moment I have:
SELECT 'http://www.'||LINK AS "URL"
FROM TABLE
If selecting only rows from TABLE where LINK IS NOT NULL isn't an option, you can use NVL2() for this. It accepts three arguments - a string, the value to return if the string is not null, and the value to return if the string is null.
SELECT NVL2(LINK, 'http://www.'||LINK, NULL) AS "URL" FROM TABLE;
You could use NVL2 as the other answer suggested. Or alternatively do something like -
SELECT CASE WHEN LINK IS NOT NULL THEN
'http://www.' || LINK
ELSE
NULL
END
AS "URL"
FROM TABLE;
I would go even further. You have Oracle so you have regular expressions at your disposal (or you do if you have 9i or greater), so you can check to see if your link already starts with http://:
SELECT CASE WHEN REGEXP_LIKE(link, '^https?:\/\/') THEN link
WHEN link IS NOT NULL THEN 'http://www.' || link END AS url
FROM mytable;
The CASE statement will return NULL if there is no ELSE clause, so you need not add an explicit case for link IS NULL. Personally, I would go so far as to make sure that link didn't start with www. as well, or if it even should.