Oracle SQL show null value - sql

I am trying to do the following query:
SELECT column1,column2,column3
FROM tablename
WHERE
column1 IN
('string1','string2','string3','string4')
AND column2='some_value';
The results show only:
String1, string2,string3 because string4 does not have an equivalent some_value in column2.
How can I show all 4 values with the 4th showing as null like:
Column1|column2|column3
+----------------------+
|string1 value value |
|string2 value value |
|string3 value value |
|string4 null null |
+----------------------+

SELECT column1,column2,column3
FROM tablename
WHERE
column1 IN
('string1','string2','string3','string4')
AND column2='some_value'
OR (column2 is null or column3 is null);
You should saycolumn2 is null at the end. as it doesn't correspond to your where condition.

Add OR
SELECT column1,column2,column3
FROM tablename
WHERE
column1 IN ('string1','string2','string3','string4')
AND (
column2='some_value'
OR column2 is null
);

In this case the treatment is diferent, if value of column2 is only diferent from "some value" (parameter) return all lines.
- In this case:
- column2 with diferent value from parameter will be returned with empty value on column2 and column3.
- column2 with null value will be returned
SELECT column1, CASE WHEN column2 = 'some value' THEN COLUMN2 ELSE NULL END column2, CASE WHEN column2 = 'some value' THEN column3 ELSE NULL END column3
FROM TABLENAME
WHERE
column1 IN
('string1','string2','string3','string4')
AND (column2='value' OR column2 = COLUMN2 OR column2 IS null);

Related

Transform SQL Server table based on calculation

I have a table like below
Column1
Column2
A
200
A
200
A
0
B
300
B
200
C
100
I would like to transform this table into the following table
With calculation: for each element of column1, SUM (column2) / count of (non-zero column2)
Column1
Column2
A
((200+ 200 + 0) / 2) = 200
B
((300 + 200) / 2) = 250
C
100 / 1 = 100
The only thing I can think of is looping through distinct elements of Column1 and run:
SELECT SUM(Column2)
FROM Table
WHERE Column1 = i / (SELECT COUNT(Column2)
FROM Table
WHERE Column1 = i AND Column2 <> 0)
and generate a table.
Is there a better way of doing this?
Use aggregation:
SELECT Column1,
SUM(Column2) / COUNT(CASE WHEN Column2 <> 0 THEN 1 END) AS Column2
FROM yourTable
GROUP BY Column1
HAVING COUNT(CASE WHEN Column2 <> 0 THEN 1 END) > 0;
You can use where clause to remove rows with 0 in column2 then use aggregation to have your desired result. But it will remove those column1 values which have 0 in all columnd2.
But Query2 will return rows with zero values in column2 instead of removing the removing the row.
Schema and insert statements:
create table testTable (Column1 varchar(50), Column2 int);
insert into testTable values('A', 200);
insert into testTable values('A', 200);
insert into testTable values('A', 0);
insert into testTable values('B', 300);
insert into testTable values('B', 200);
insert into testTable values('C', 100);
insert into testTable values('D', 0);
Query1:
SELECT Column1,
SUM(Column2) / COUNT(*) AS Column2
FROM testTable where column2<>0
GROUP BY Column1;
Output:
Column1
Column2
A
200
B
250
C
100
Query2:
SELECT Column1,
Coalesce(SUM(Column2) / nullif(COUNT(CASE WHEN Column2 <> 0 THEN 1 END),0),0) AS Column2
FROM testTable
GROUP BY Column1;
Output:
Column1
Column2
A
200
B
250
C
100
D
0
db<>fiddle here
You can go for derived table to filter out the 0 column2 rows. Then, you can apply GROUP BY.
declare #table table (Column1 char(1), Column2 int)
insert into #table values
('A',200),
('A',200),
('A',0 ),
('B',300),
('B',200),
('C',100);
SELECT Column1, (sum(column2) / count(column2) ) as column2
from
(
SELECT * FROM #TABLE where Column2 <> 0) as t
group by Column1
Column1
column2
A
200
B
250
C
100
Retrieve distinct value of column1 and ignore zero value of column2 while division with total sum of column2. And also consider here divide by zero error.
-- SQL Server
SELECT t.column1
, t.column2 / (CASE WHEN (t.total - t.total_zero) = 0 THEN 1 ELSE (t.total - t.total_zero) END)
FROM (SELECT column1
, SUM(column2) column2
, COUNT(CASE WHEN column2 = 0 THEN 1 END) total_zero
, COUNT(1) total
FROM test
GROUP BY column1) t
Please check this url https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=3853456941909ffffb8792415adc1f6f
Use AVG() window function because you want the average value of Column2.
If you want all the values of Column1 in the results even if they have only 0s in Column2:
SELECT DISTINCT Column1,
AVG(CASE WHEN Column2 <> 0 THEN Column2 END) OVER (PARTITION BY Column1) Column2
FROM tablename;
If you want results for the values of Column1 that have at least 1 Column2 not 0:
SELECT DISTINCT Column1,
AVG(Column2) OVER (PARTITION BY Column1) Column2
FROM tablename
WHERE Column2 <> 0;
See the demo.
Note that SQL Server truncates the average of integers to an integer, so if you want the result as a floating point number you should multiply Column2 by 1.0, like:
AVG(CASE WHEN Column2 <> 0 THEN 1.0 * Column2 END)
or:
AVG(1.0 * Column2)

How to grab records that have NULL or certain character

I have TWO column that contains NULL values and character "//" and valid values on both. I want to select all the rows that have NULL OR the character "//" in the first column and valid character in the second column. Is there a way to do this? I keep getting an error when I run this:
Does not work:
select COLUMN1 IS NULL OR LIKE '%//%' AND COLUMN2 NOT LIKE '%//%'
from TABLE
Works:
select COLUMN1 LIKE '%//N%' AND COLUMN2 NOT LIKE '%//%'
from TABLE
How can I make the first statement work? To check for columns that have "//" OR has NULL values in the first column?
Based on your description, you need to use parenthesis around your junction and disjunction (or, and) operators:
create or replace temp table foo (COLUMN1 string, COLUMN2 string);
insert into foo (COLUMN1, COLUMN2) values ('//',null), ('okay', null), ('okay', 'okay'), (null, 'okay'), ('//', 'okay');
select * from foo where
(COLUMN1 = '//' or COLUMN1 is null) and (COLUMN2 <> '//' and COLUMN2 is not null)
As I understand the requirement, this will only select the final two rows that have // or NULL for the first column and valid values for the second column.
You can try to use UNION to achieve the same result.
select COLUMN1 LIKE '%//N%' AND COLUMN2 NOT LIKE '%//%'
from TABLE
union
select COLUMN1 IS NULL AND COLUMN2 NOT LIKE '%//%'
from TABLE
try this
create or replace table test_1 as
(SELECT '1' as fld1, NULL as fld2 UNION ALL
SELECT '//' as fld1, NULL as fld2 UNION ALL
SELECT '21' as fld1, '5444' as fld2 UNION ALL
SELECT '//' as fld1 , '25' as fld2 UNION ALL
SELECT NULL as fld1, '//' as fld2 UNION ALL
SELECT '4500' as fld1 , '23' as fld2 UNION ALL
SELECT NULL as fld1 , '12' as fld2 );
--I want to select all the rows that have NULL OR the character "//" in the first column
--and valid character in the second column.
select * from test_1 WHERE (fld1 is NULL and (fld2 <> '//' and fld2 is not null ))
OR (fld1 = '//' and (fld2 <> '//' and fld2 is not null ));

How to not apply logic in SQL where block to all when blocks

So I have the following SQL statement:
SELECT column1
FROM (
SELECT
CASE
WHEN column2 IN (1, 2) THEN 'name2' // line 5
WHEN column2 IN (3, 4) THEN 'name3' // line 6
ELSE 'UNKNOWN'
END AS column1
FROM table
WHERE
column3 IS null
AND column4=True // line 12 <==== How do I apply this logic to ONLY line 6 and NOT line 5?
) AS name4
GROUP BY column1
I don't know how to just apply the logic in line 12 to only affect line 6 and not line 5. I've tried:
AND column4=True AND column2 NOT IN (3, 4)
But this isn't working.
Your logic is close, but it is slightly different:
SELECT DISTINCT
(CASE WHEN column2 IN (1, 2) THEN 'name2' // line 5
WHEN column2 IN (3, 4) THEN 'name3' // line 6
ELSE 'UNKNOWN'
END) AS column1
FROM table
WHERE column3 IS null AND
(column4 = True OR column2 NOT IN (3, 4))
Note: the query in your question can be simplified. The subquery is unnecessary.
It might be easier to follow the logic as:
WHERE column3 IS null AND
NOT (column4 <> True AND column2 IN (3, 4))

How do I delete the last row(which is all NULLs) in my database?

Column1 Column2 Column3 Column4 Column5 Column6
NULL NULL NULL NULL NULL NULL
I have tried the following queries:
1.
Delete from tablename where column1 = NULL
2.
Delete from tablename where column1 IS NULL
The second query completed successfully but it said 0 rows affected.
You must use the special syntax is null when attempting to match a null value:
delete from mytable
where Column1 is null
and Column2 is null
and Column3 is null
and Column4 is null
and Column5 is null
and Column6 is null;
Any regular comparison with null is always false,
eg both Column1 = null and Column1 != null are always false
I believe this or equivalent for your rdbms should work.
It deletes rows if the return value of the isnull function is equal to an empty string.
DELETE FROM tablename
WHERE isnull(Column1, '') = ''
DELETE FROM table WHERE coalesce(col1,col2,col3,...) IS NULL

How to view a string or update a column on a database table depending on the values of other columns?

I have a database table like that :-
Table1
Column1 : Varchar(50)
Column2 : Varchar(50)
Column3 : Boolean
Column4 : Varchar(50)
Column5 : Varchar(50)
I would like to create a dummy column -or add a new column to the table- when running a SQL statement so that the value is that column will hold a string indicating the satus of the row item depeing on more than one of these columns. I mean wether these columns have Null values or not.
A logical way to represent that:-
Select switch DummyColumn
"status1" Case column1 IS NOT NULL
"status2" Case column2 IS NOT NULL
"status3" Case column3 IS NOT NULL
"status4" Case column1 IS NOT NULL AND column2 IS NOT NULL
"status5" Case column2 IS NOT NULL AND column3 IS NULL
"status6" Case column2 IS NOT NULL OR column3 IS NOT NULL
From Table1;
In Business Logic, I can say I want to make display a string indicating the status of an Item in the database depeding on many other status columns which may be boolen or string and this status can have many values according to the values stored in these table columns.
My database engine is Sybase.
How I can build my SQL query to do that ? what may be this matter called ? How I can find or search for that ? I do not know in what topic I may find this ? I search about Merging, Concatening, Replacing, NVL, and Union but i do not find what I seek for..
Thanks in Advance and I hope that I express my question well and that it is a duplicate and I hope to find a good answer for it as soon as possible ..
Using a single CASE clause:
SELECT Column1,
Column2,
Column3,
Column4,
Column5,
Column6,
CASE WHEN Column1 IS NOT NULL AND Column2 IS NOT NULL THEN 'status4'
WHEN Column2 IS NOT NULL AND Column3 IS NULL THEN 'status5'
WHEN Column1 IS NOT NULL THEN 'status1'
WHEN Column2 IS NOT NULL THEN 'status2'
WHEN Column3 IS NOT NULL THEN 'status3'
WHEN Column2 IS NOT NULL OR Column3 IS NOT NULL THEN 'status6'
END AS Dummy_Column
FROM Table1
NB. Status6 will never be returned because it will be overridden by Status1 or Status2, even where Status4 and Status5 are not applicable.
There's more than one way to skin a cat, this is one of them.
SELECT t.Column1
, t.Column2
, t.Column3
, t.Column4
, t.Column5
, t.Column6
, COALESCE(Status1, Status2, Status3, Status4, Status5, Status6) AS DummyColumn
FROM (
SELECT *
, CASE WHEN Column1 IS NOT NULL THEN 'status1' ELSE NULL END AS Status1
, CASE WHEN Column2 IS NOT NULL THEN 'status2' ELSE NULL END AS Status2
, CASE WHEN Column3 IS NOT NULL THEN 'status3' ELSE NULL END AS Status3
, CASE WHEN Column1 IS NOT NULL AND Column2 IS NOT NULL THEN 'status4' ELSE NULL END AS Status4
, CASE WHEN Column2 IS NOT NULL AND Column3 IS NULL THEN 'status5' ELSE NULL END AS Status5
, CASE WHEN Column2 IS NOT NULL OR Column3 IS NOT NULL THEN 'status6' ELSE NULL END AS Status6
FROM Table1
) t
Note that this works using SQL Server but as there are no arcane constructions involved, it should be relatively easy to convert this to SyBase.