NULL in a in UNION sql statement - sql

When I run the following query
with table_a as
(select '1' as column_name union select '2' union NULL)
select * from table_a;
I get:
Syntax error: unexpected 'NULL'.
Is there a way to insert the NULL as part of the SELECT above?

UNION requires SELECT
with table_a as
(select '1' as column_name union select '2' union SELECT NULL)
select * from table_a;
It is also possible to use VALUES:
with table_a(column_name) as
(SELECT * FROM VALUES ('1'),('2'),(NULL))
select * from table_a;

You need a query with one column all the time
with table_a as
(select '1' as column_name union select '2' union SELECT NULL)
select * from table_a;

Add select before NULL, then it should work.

your SQL is malformed in general
you need SELECT ... FROM at least
select '1' as column_name from dual
union
select '2' from dual
union
select NULL from dual;

Related

how to get the missing values in SQL query when using in clause

Suppose I have the following query :
select value from table where value in ('abc','cde','efg');
If only 'abc' is populated in the table,
I want to be able to see which value is missing in the result set,
so the results looks like :
cde
efg
You can use UNION ALL to get a resultset with all the values that you want:
SELECT 'abc' AS value FROM dual UNION ALL
SELECT 'cde' FROM dual UNION ALL
SELECT 'efg' FROM dual
(you may omit FROM dual depending on your database).
And with NOT EXISTS get all the values from the above resultset that do not appear in the table:
SELECT u.*
FROM (
SELECT 'abc' AS value FROM dual UNION ALL
SELECT 'cde' FROM dual UNION ALL
SELECT 'efg' FROM dual
) u
WHERE NOT EXISTS (SELECT 1 FROM tablename t WHERE t.value = u.value)

How to resolve missing SELECT keyword error when trying to insert select

It doesn't matter how I write this statement, I always get the ORA-00928 missing select keyword error.
I'm trying to insert values from a query into a table. The result of the query has the same amount of columns as the table where it needs to be inserted to. I have tried making it as an CTE. Even a select-query from an existing table returns the same error.
Code is like:
WITH FIRST_CTE(FrstCol1,FrstCol2)
AS
(
SELECT 't', '1' from dual UNION ALL
SELECT 's', '2' from dual
)
,
SECOND_CTE(SndCol1,SndCol2)
AS
(
SELECT 't', '3' from dual UNION ALL
SELECT 'z', '4' from dual
)
INSERT INTO TABLE_1
SELECT *
from
(SELECT * FROM FIRST_CTE) A
JOIN
(SELECT * FROM SECOND_CTE) B
ON A.FrstCol1 = B.SndCol1
;
Any suggestions?
No problem occurs if you put INSERT part to the beginning, since SELECT statement starts by WITH clause ( for this case )
INSERT INTO TABLE_1
WITH FIRST_CTE(FrstCol1,FrstCol2)
AS
(
SELECT 't', '1' from dual UNION ALL
SELECT 's', '2' from dual
)
,
SECOND_CTE(SndCol1,SndCol2)
AS
(
SELECT 't', '3' from dual UNION ALL
SELECT 'z', '4' from dual
)
SELECT *
from
(SELECT * FROM FIRST_CTE) A
JOIN
(SELECT * FROM SECOND_CTE) B
ON A.FrstCol1 = B.SndCol1;
provided that TABLE_1 is such a table that is created as
create table TABLE_1(FrstCol1 varchar2(100),FrstCol2 varchar2(100),
SndCol1 varchar2(100), SndCol2 varchar2(100))

sql how to return a list in a condition

I am new with SQL and I would like to ask for your help concerning a problem that I am facing
the first query query1 that can return 0 or 1 line:
with query1 as (select ... from table) select * from query1
returns
query1
-
or
query1
4567
also a second request returning a list:
with my_list as (select 'a' from dual union all select 'b' from dual) select * from my_list
returns
my_list
a
b
my problem is the following: I can not condition my first query so that in case query1 returns null then I display my_list.
I tried with this :
with my_list as (select 'a' from dual union all select 'b' from dual)
select case when ( ( select '' from dual /* case when query1 returns nothing */ ) is null )
then (select 'a' from dual union all select 'b' from dual) /* my_list */
else (select '' from dual) end
from my_list;
but i have the following error :
ORA-01427: single-row subquery returns more than one row
what is this error?
what i want to do is that :
with my_list as (select 'a' from dual union all select 'b' from dual),
myquery as (select '' from dual)
select case when ( myquery is null )
then (select my_list)
else (select myquery end)
so that this query have to return
a
b
thanks for your help
I think you want union all:
with query1 as (select ... from table) select * from query1,
my_list as ( . . . )
select q.*
from query1 q
where ? is not null
union all
select ml.*
from my_list ml
where not exists (select 1 from query1 where ? is not null);
? is for the column returned by query1.
thanks for your help Gordon but I run this query
with query1 as (select '' from dual), my_list as (select 'a' from dual union all select 'b' from dual)
select q.* from query1 q
union select ml.* from my_list ml
where not exists (select 1 from query1);
it returns null value in stead of returning my_list

Can I have dynamic FROM Clause in SQL?

I'm currently working with my report parameter list of value that is dependent in another parameter.
I have come up with this idea, is there any possible way to for this to work?
WITH A AS (
SELECT DISTINCT columnA1 FROM Table1
UNION SELECT DISTINCT columnA2 FROM Table1
UNION SELECT DISTINCT columnA3 FROM Table1)
WITH B AS (SELECT DISTINCT columnB1 FROM Table1
UNION SELECT DISTINCT columnB2 FROM Table1
UNION SELECT DISTINCT columnB3 FROM Table1)
Select * from CASE WHEN (:PM_Parameter1 = 'A')
THEN A
ELSE B
END;
Assuming this is Oracle SQL, you can use a the EXISTS function to check for the parameter value, then combine the sets using UNION.
Try playing with this SQL:
select * from
(
select 'A' from dual
union
select 'B' from dual
)
where exists
(SELECT 'Y'
FROM dual
where 'parameter' = 'parameter'
)
union
select * from
(
select 'X' from dual
union
select 'Y' from dual
)
where exists
(SELECT 'Y'
FROM dual
where 'parameter' != 'parameter'
)
If you reverse both the conditions 'parameter' = 'parameter' and 'parameter' != 'parameter', it will return two different row sets.
I am sure this can be optimized again, hope it works out for you.

cross-dbms way to check if string is numeric

Ok, I have this field: code varchar(255). It contains some values used in our export routine like
DB84
DB34
3567
3568
I need to select only auto-generated (fully numeric) fields
WHERE is_numeric(table.code)
is_numeric() checks if code field contains only positive digits.
Can you propose anything that will work both under mysql 5.1 and oracle 10g?
Below are three separate implementations for each of SQL Server, MySQL and Oracle. None use (or can) the same approach, so there doesn't seem to be a cross DBMS way to do it.
For MySQL and Oracle, only the simple integer test is show; for SQL Server, the full numeric test is shown.
For SQL Server:
note that isnumeric('.') returns 1.. but it can not actually be converted to float. Some text like '1e6' cannot be converted to numeric directly, but you can pass through float, then numeric.
;with tmp(x) as (
select 'db01' union all select '1' union all select '1e2' union all
select '1234' union all select '' union all select null union all
select '1.2e4' union all select '1.e10' union all select '0' union all
select '1.2e+4' union all select '1.e-10' union all select '1e--5' union all
select '.' union all select '.123' union all select '1.1.23' union all
select '-.123' union all select '-1.123' union all select '--1' union all
select '---1.1' union all select '+1.123' union all select '++3' union all
select '-+1.123' union all select '1 1' union all select '1e1.3' union all
select '1.234' union all select 'e4' union all select '+.123' union all
select '1-' union all select '-3e-4' union all select '+3e-4' union all
select '+3e+4' union all select '-3.2e+4' union all select '1e1e1' union all
select '-1e-1-1')
select x, isnumeric(x),
case when x not like '%[^0-9]%' and x >'' then convert(int, x) end as SimpleInt,
case
when x is null or x = '' then null -- blanks
when x like '%[^0-9e.+-]%' then null -- non valid char found
when x like 'e%' or x like '%e%[e.]%' then null -- e cannot be first, and cannot be followed by e/.
when x like '%e%_%[+-]%' then null -- nothing must come between e and +/-
when x='.' or x like '%.%.%' then null -- no more than one decimal, and not the decimal alone
when x like '%[^e][+-]%' then null -- no more than one of either +/-, and it must be at the start
when x like '%[+-]%[+-]%' and not x like '%[+-]%e[+-]%' then null
else convert(float,x)
end
from tmp order by 2, 3
For MySQL
create table tmp(x varchar(100));
insert into tmp
select 'db01' union all select '1' union all select '1e2' union all
select '1234' union all select '' union all select null union all
select '1.2e4' union all select '1.e10' union all select '0' union all
select '1.2e+4' union all select '1.e-10' union all select '1e--5' union all
select '.' union all select '.123' union all select '1.1.23' union all
select '-.123' union all select '-1.123' union all select '--1' union all
select '---1.1' union all select '+1.123' union all select '++3' union all
select '-+1.123' union all select '1 1' union all select '1e1.3' union all
select '1.234' union all select 'e4' union all select '+.123' union all
select '1-' union all select '-3e-4' union all select '+3e-4' union all
select '+3e+4' union all select '-3.2e+4' union all select '1e1e1' union all
select '-1e-1-1';
select x,
case when x not regexp('[^0-9]') then x*1 end as SimpleInt
from tmp order by 2
For Oracle
case when REGEXP_LIKE(col, '[^0-9]') then col*1 end