Select only when first select is null - sql

I really dont get this, tried with coalesce() but with no result...
I have one select (very simplified to understand the problem):
select col1,
col2
from table1 t1
where table1.col1='value'
and table1.col2='value2'
and table1.col3='value3'
And i really need a result so if this select resultset is null (and only if it is null) (no result) then the following sql select came to picture
select col1,
col2
from table1 t1
where table1.col1='another_value'
and table1.col2='another_value2'
How can i get this two in to one big select? (any syntax which is recommended is appreciated...)

Something like:
; WITH Base AS (
select col1,
col2
from table1 t1
where table1.col1='value'
and table1.col2='value2'
and table1.col3='value3'
)
, Base2 AS (
select col1,
col2
from table1 t1
where table1.col1='another_value'
and table1.col2='another_value2'
AND NOT EXISTS (SELECT 1 FROM Base) -- HERE!!!
)
SELECT * FROM Base
UNION
SELECT * FROM Base2
and let's hope the SQL optimizer won't run the first query twice :-)
It is a CTE (Common Table Expression)... I used it so I could reuse the first query twice (one in the EXISTS and the other in the SELECT ... UNION)
By using a temporary table
select col1,
col2
INTO #temp1 -- HERE!!!
from table1 t1
where table1.col1='value'
and table1.col2='value2'
and table1.col3='value3'
select col1,
col2
from table1 t1
where table1.col1='another_value'
and table1.col2='another_value2'
AND NOT EXISTS (SELECT 1 FROM #temp1) -- HERE!!!

It could benefit us a little better if you had a little more information in your example. Is there a common value between the two tables that a JOIN can be established?
SELECT col1
,col2
FROM Table1 t1
WHERE table1.col1='value'
and table1.col2='value2'
and table1.col3='value3'
UNION
SELECT col1
,col2
FROM Table2 t2
WHERE table1.col1='another_value'
and table1.col2='another_value2'
WHERE NOT EXISTS (SELECT 1 FROM Table1 t1 WHERE t1.Col1 = t2.Col2)

You can use COALESCE, like this:
select COALESCE (
(select col1,
col2
from table1 t1
where table1.col1='value'
and table1.col2='value2'
and table1.col3='value3')
,
(select col1,
col2
from table1 t1
where table1.col1='another_value'
and table1.col2='another_value2')
)

Here are my ugly solution.
select top 1 with ties
col1,
col2
from table1
where (
col1='value'
and col2='value2'
and col3='value3'
) OR
(
col1='another_value'
and col2='another_value2'
)
order by
CASE
WHEN col1='value'
and col2='value2'
and col3='value3'
THEN 1
WHEN col1='another_value'
and col2='another_value2'
THEN 2 END
SQL Fiddle DEMO

Related

Remove duplicate rows from one column

The problem is:
select (..)
UNION
select (..)
Result is:
Col1, Col2, Col3
Val1 Text1 Data
Val1 Text2 Data
The problem is that i need to save only 1 row of this two. Col2 value is not same at fact, but the same in business logic.
So, how to get result like this:
Col1, Col2,Col3
Val1 Text1 Data
OR
Col1, Col2, Col3
Val1 Text2 Data
Thank you!
You can place the UNION in a subquery and group again
SELECT
Col1,
MIN(Col2),
Col3
FROM (
SELECT Col1, Col2, Col3
FROM table1 t1
UNION ALL
SELECT Col1, Col2, Col3
FROM table2 t2
) t
GROUP BY
Col1,
Col2;
Note the use of UNION ALL rather than UNION, because you are grouping anyway it is not necessary to de-duplicate first.
Hmmm . . . If you want one row per val, then one method is:
with t1 as ( < query 1 here > ),
t2 as ( < query 2 here > )
select t1.*
from t1
union all
select t2.*
from t2
where not exists (select 1 from t1 where t1.val = t2.val);

Use postgres CTE in multiple queries

I can use a CTE in a single query like this
with mycte as (...)
insert into table1 (col1) select col1 from mycte where col1 in
(select col1 from mycte)
But what if I want to use mycte in multiple queries? How can I make something like this work?
with mycte as (...)
insert into table1 (col1) select col1 from mycte where col1 in
(select col1 from mycte),
insert into table2 (col1) select col1 from mycte where col1 in
(select col1 from mycte)
For multiple inserts, you can put them into the same query:
with mycte as (...),
i1 as (
insert into table1 (col1)
select col1
from mycte
where col1 in (select col1 from mycte)
returning *
)
insert into table2 (col1)
select col1
from mycte
where col1 in (select col1 from mycte);
A CTE is an ad-hoc view. If you want a permanent view that you can use in multiple queries, then use CREATE VIEW instead.

How to achieve the results into a single row?

I have the below
;with cte as(
Select 1 as Col1 ,NULL as Col2
Union All
Select Null ,2)
select *
from cte
/* Result*/
Col1 Col2
1 NULL
NULL 2
I am looking for
Col1 Col2
1 2
i.e. results should come in a single row.
How can we achieve this?
Without more details about your data, it seems like applying a simple aggregate function like max should do what you are after:
...
select max(col1) as col1, max(col2) as col2
from cte
SELECT MAX(col1) , MAX(col2) FROM cte
You can use any aggregate function like Max() or Min() or Sum() depends on your requirement
.
1With the limited information in your question is this what your trying achieve?
;with cte as(
Select table1.Col1 , table2.Col2 From Table1
JOIN table2
ON table1.col1 = table2.Col1
WHERE table1.Col1 = 1 and table2.Col2 = 2
)
select *
from cte
Using cartesian join we can get the required result:
select t2.a,t1.b from table t1,table t2 where t1.b is not null and t2.a is not null;

SQL query to simulate distinct

SELECT DISTINCT col1, col2 FROM table t ORDER BY col1;
This gives me distinct combination of col1 & col2. Is there an alternative way of writing the Oracle SQL query to get the unique combination of col1 & col2 records with out using the keyword distinct?
Use the UNIQUE keyword which is a synonym for DISTINCT:
SELECT UNIQUE col1, col2 FROM table t ORDER BY col1;
I don't see why you would want to but you could do
SELECT col1, col2 FROM table_t GROUP BY col1, col2 ORDER BY col1
Another - yet overly complex and somewhat useless - solution:
select *
from (
select col1,
col2,
row_number() over (partition by col1, col2 order by col1, col2) as rn
from the_table
)
where rn = 1
order by col1
select col1, col2
from table
group by col1, col2
order by col1
or a less elegant way:
select col1,col2 from table
UNION
select col1,col2 from table
order by col1;
or a even less elegant way:
select a.col1, a.col2
from (select col1, col2 from table
UNION
select NULL, NULL) a
where a.col1 is not null
order by a.col1
Yet another ...
select
col1,
col2
from
table t1
where
not exists (select *
from table t2
where t2.col1 = t1.col1 and
t2.col2 = t1.col2 and
t2.rowid > t1.rowid)
order by
col1;
Variations on the UNION solution by #aF. :
INTERSECT
SELECT col1, col2 FROM tableX
INTERSECT
SELECT col1, col2 FROM tableX
ORDER BY col1;
MINUS
SELECT col1, col2 FROM tableX
MINUS
SELECT col1, col2 FROM tableX WHERE 0 = 1
ORDER BY col1;
MINUS (2nd version, it will return one row less than the other versions, if there is (NULL, NULL) group)
SELECT col1, col2 FROM tableX
MINUS
SELECT NULL, NULL FROM dual
ORDER BY col1;
Another ...
select col1,
col2
from (
select col1,
col2,
rowid,
min(rowid) over (partition by col1, col2) min_rowid
from table)
where rowid = min_rowid
order by col1;

grouping IN statement sql

lets say I have a table called table1 and it's corresponding columns are col1, col2, col3 and col4 for example.
what will be the equivalent thing of doing:
-- note that the following query will not work
SELECT *
FROM table1
WHERE col1, col2 IN (SELECT col1, col2
FROM table1
WHERE col3 < 4)
Do I have to merge col1 and col2 in my database to make this work? If I merge col1 and col2 into col1_2 then I will be able to make the above query work by writing:
SELECT *
FROM table1
WHERE col1_2 IN (SELECT col1_2
FROM table1
WHERE col3 < 4)
The IN clause works fine when using one column. it will be nice if I could use it with several columns without having to modify the database.
SELECT * from table1 t1, table1 t2
where t1.col1=t2.col1 and t1.COl2=t2.Col2 and t1.col3<4
try this one
Equivalent of what you showed is:
SELECT *
FROM table1 tb1
WHERE EXISTS
(
SELECT *
FROM table1 tb2
WHERE
tb1.col1 = tb2.col1 and
tb1.col2 = tb2.col2 and
tb2.col3 < 4
)
However, this query does not make much sense as it is equivalent of
SELECT *
FROM table1 tb1
WHERE tb2.col3 < 4
I just assume that the example you show is not well thought out.