UPDATING a table which is selected using SELECT query in SQL - sql

I want to use the Update keyword with select something like
UPDATE(select col1,col2,col3 from UNPIVOTED_TABLE)
SET col1=0
WHERE col1 IS NULL
SET col2=0
WHERE col2 is NULL
SET col3=0
WHERE col3 is NULL
I know my syntax is not right but this basically is what i am trying to achieve
I am selecting 3 columns and there are some null values which i want to update and set it as 0
Also i cannot update the table itself since the original table was UNPIVOTED and i am PIVOTING it in the select statement and i need the pivoted result (that is the columns i have selected) (col1,col2,col3)
Also i am using amazon Athena if that is relevant

If I followed you correctly, you just want coalesce():
select
coalesce(col1, 0) col1,
coalesce(col2, 0) col2,
coalesce(col3, 0) col3
from unpivoted_table
colaesce() checks if the first argument is null: if it doesn't, it returns the original value as-is, otherwise it returns the value given a second argument instead.

In case you are using Athena, I can assume you have read only access and cannot really update the original data.
In your case, if you'd like to represent the nulls as 0 you can use `IFNULL(column, 0)
For more information about IFNULL you can read here

Related

Need to replace all the null values with '0' in Vertica

I have a vertica table, "CUSTOMER" which contains around 10 columns. Each column contains few null values. So I have to write one query which will replace all the null values to '0'.
Is it possible to do it in vertica. Can anyone please help me on that.
You use coalesce():
select coalesce(col1, 0) as col1, . . .
from t;
You can incorporate similar logic into an update as well.
In a SELECT, as #GordonLinoff says, you use COALESCE(), or the slightly faster NVL(), IFNULL() or ISNULL() functions (they are all synonyms of each other and take exactly two arguments, while COALESCE() is more flexible - at a cost - with a variable-length argument list, returning the first non-null value of a list of arguments of varying length).
For updating, strive to update only the rows you need to update, and go, for each column:
UPDATE t SET col1=0 WHERE col1 IS NULL;
UPDATE t SET col2=0 WHERE col2 IS NULL;
Well, in an extreme case, you might end up updating the same row as often as its number of columns, then you have won nothing - but it's worth planning to minimise how often you update.
Or, you might consider:
UPDATE t SET
col1 = NVL(col1,0)
, col2 = NVL(col2,0)
, col3 = NVL(col3,0)
[...]
WHERE col1 IS NULL
OR col2 IS NULL
OR col3 IS NULL
[...]
;
Being columnar, and due to the fact that each UPDATE, in Vertica, is a DELETE and an INSERT anyway, it makes no difference if you update just one column or all columns.

Trying to create cleaner sql syntax

Here is what I am trying to do:
select * from table
where in ('completedDate', 'completedBy', 'cancelDate', 'cancelBy') is not null
If the four columns above are not null I need to display the records. I know I would do this with several where/and clauses but trying to learn and make my new stuff cleaner.
Is what I am trying to do above possible in a cleaner way?
If I understand correctly I guess you want to do that:
select *
from table
where completedDate is not null
and completedBy is not null
and cancelDate is not null
and cancelBy is not null
Regarding clarity of code I don't see a better way to write it, that's what I would code anyway.
EDIT: I wouldn't really do that in this case, but if this is a very common condition you can add a computed column in the table (stored or not), or create a view on top of table, and do:
select * from view where importantFieldsAreNotNull = 1
If I understand correctly, you want to return records where all four columns are not null?
The standard and (in my opinion) most readable way to do this would be:
Select
*
From
YourTable
Where
Column1 IS NOT NULL AND
Column2 IS NOT NULL AND
Column3 IS NOT NULL AND
Column4 IS NOT NULL;
To Check if all Columns are not null:
select * from table
where completedDate is not null
and completedBy is not null
and cancelDate is not null
and cancelBy is not null
You could use the COALESCE function to determine if all the column values were NULL.
The COALESCE function takes between 1 or more arguments and returns the first non-null argument. If at least one of the arguments passed into COALESCE is NOT NULL, then it will return that value, otherwise if all the arguments are NULL it returns NULL.
SELECT *
FROM TABLE
WHERE COALESCE(Column1, Column2, Column3, Column4) IS NOT NULL
Also depending on the datatypes of the columns, you may have to CAST them to the same datatype. For example, I wasn't able to use the COALECSE function on a DateTime column and a CHAR column without casting.
However, even though this would be shorter, I would not consider it "cleaner". I'd think it would be harder to read and maintain compared to having multiple ANDs in the WHERE clause.
-- Under reasonable assumption on data types:
select *
from [table]
where completedBy+cancelBy+DATENAME(yy,completedDate)+ DATENAME(yy,cancelDate)
is not null

SQL: What does NULL as ColumnName imply

I understand that AS is used to create an alias. Therefore, it makes sense to have one long name aliased as a shorter one. However, I am seeing a SQL query NULL as ColumnName
What does this imply?
SELECT *, NULL as aColumn
Aliasing can be used in a number of ways, not just to shorten a long column name.
In this case, your example means you're returning a column that always contains NULL, and it's alias/column name is aColumn.
Aliasing can also be used when you're using computed values, such as Column1 + Column2 AS Column3.
When unioning or joining datasets using a 'Null AS [ColumnA] is a quick way to make sure create a complete dataset that can then be updated later and a new column does not need to be created in any of the source tables.
In the statement result we have a column that has all NULL values. We can refer to that column using alias.
In your case the query selects all records from table, and each result record has additional column containing only NULL values. If we want to refer to this result set and to additional column in other place in the future, we should use alias.
It means that "aColumn" has only Null values. This column could be updated with actual values later but it's an empty one when selected.
---I'm not sure if you know about SSIS, but this mechanism is useful with SSIS to add variable value to the "empty" column.
When using SELECT you can pass a value to the column directly.
So something like :
SELECT ID, Name, 'None' AS Hobbies, 0 AS NumberOfPets, NULL AS Picture, '' AS Adress
Is valid.
It can be used to format nicely a query output when using UNION/UNION ALL.
Query result can have a new column that has all NULL values. In SQL Server we can do it like this
SELECT *, CAST(NULL AS <data-type>) AS as aColumn
e.g.
SELECT *, CAST(NULL AS BIGINT) AS as aColumn
How about without using the the as
SELECT ID
, Name
, 'None' AS Hobbies
, 0 AS NumberOfPets
, NULL Picture
Usually adding NULL as [Column] name at the end of a select all is used when inserting into another table a calculated column based on the table you have just selected.
UPDATE #TempTable SET aColumn = Column1 + Column2 WHERE ...
Then exporting or saving the results to another table.

SQL: Output default string for NULL column

I am playing with sqlplus command prompt, I want to display a default string, lets say 'ITISNULL' for all NULL columns without updating them.
select * from enrollments where ....
Enrollments is a table which might contain null in its lgrade column. I dont want to update it but just want an output string say, "to be graded" to be printed in its place.
Is there any SQL function I can use for this?
There are a couple ways to do this. One option is to use COALESCE:
SELECT COALSECE(lgrade, 'to be graded')...
You can't specify * for all fields, you'll have to specify each column name accordingly.
NVL is your answer, you will need to do for every column that could have nulls values
http://www.techonthenet.com/oracle/functions/nvl.php
In SQL*Plus you can use SET NULL:
SQL> SET NULL 'ITISNULL'
SQL> SELECT ...
All NULL results will display as ITISNULL. The only problem is that columns with a width of less than 8 (the length of ITISNULL) may wrap - at least they do in my older version of SQL*Plus (9.2).
To return SQL*Plus to its default, issue the following:
SQL> SET NULL ''
there are plenty of ways to show a string when the column is null. As mentioned above, some of the ways :-
Use NVL to display 'itisnull' whenever the value of col1 is null.
select nvl(col1, 'itisnull') from tableName;
Use CASE to display 'itisnull' whenever the value of col1 is null.
select
case when col1 is null then
'itisnull'
else col1
end colum from tableName;

How should I deal with null parameters in a PL/SQL stored procedure when I want to use them in comparisons?

I have a stored procedure with a parameter name which I want to use in a where clause to match the value of a column i.e. something like
where col1 = name
Now of course this fails to match null to null because of the way null works. Do I need to do
where ((name is null and col1 is null) or col1 = name)
in situations like this or is there a more concise way of doing it?
You can use decode function in the following fashion:
where decode(col1, name, 0) is not null
Cite from SQL reference:
In a DECODE function, Oracle considers
two nulls to be equivalent.
I think your own suggestion is the best way to do it.
What you have done is correct. There is a more concise way, but it isn't really better:
where nvl(col1,'xx') = nvl(name,'xx')
The trouble is, you have to make sure that the value you use for nulls ('xx' is my example) couldn't actually be a real value in the data.
If col1 is indexed, it would be best (performance-wise) to split the query in two:
SELECT *
FROM mytable
WHERE col1 = name
UNION ALL
SELECT *
FROM mytable
WHERE name IS NULL AND col1 IS NULL
This way, Oracle can optimize both queries independently, so the first or second part won't be actually executed depending on the name passed being NULL or not.
Oracle, though, does not index NULL values of fields, so searching for a NULL value will always result in a full table scan.
If your table is large, holds few NULL values and you search for them frequently, you can create a function-based index:
CREATE INDEX ix_mytable_col1__null ON mytable (CASE WHEN col1 IS NULL THEN 1 END)
and use it in a query:
SELECT *
FROM mytable
WHERE col1 = name
UNION ALL
SELECT *
FROM mytable
WHERE CASE WHEN col1 IS NULL THEN 1 END = CASE WHEN name IS NULL THEN 1 END
Keep it the way you have it. It's more intuitive, less buggy, works in any database, and is faster. The concise way is not always the best. See (PLSQL) What is the simplest expression to test for a changed value in an Oracle on-update trigger?
SELECT * FROM table
WHERE paramater IS NULL OR column = parameter;