Use postgres CTE in multiple queries - sql

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.

Related

How do I combine multiple tables into one new table? All of the columns headers are the same and in the same order

I have 12 tables in SQL Server with the exact same columns that I would like to combine into one brand new table. I don't want any data/rows deleted.
Thanks
Use union all:
insert into NewTable(col1, col2)
select col1, col2
from(
select col1, col2 from Table1
union all
select col1, col2 from Table2
union all
select col1, col2 from Table3
.....
)t
You can create new table while selecting like:
select col1, col2
into NewTable
from(
select col1, col2 from Table1
union all
select col1, col2 from Table2
union all
select col1, col2 from Table3
.....
)t

Select only when first select is null

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

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;

Add Identity column to a view in SQL Server 2008

This is my view:
Create View [MyView] as
(
Select col1, col2, col3 From Table1
UnionAll
Select col1, col2, col3 From Table2
)
I need to add a new column named Id and I need to this column be unique so I think to add new column as identity. I must mention this view returned a large of data so I need a way with good performance, And also I use two select query with union all I think this might be some complicated so what is your suggestion?
Use the ROW_NUMBER() function in SQL Server 2008.
Create View [MyView] as
SELECT ROW_NUMBER() OVER( ORDER BY col1 ) AS id, col1, col2, col3
FROM(
Select col1, col2, col3 From Table1
Union All
Select col1, col2, col3 From Table2 ) AS MyResults
GO
The view is just a stored query that does not contain the data itself so you can add a stable ID. If you need an id for other purposes like paging for example, you can do something like this:
create view MyView as
(
select row_number() over ( order by col1) as ID, col1 from (
Select col1 From Table1
Union All
Select col1 From Table2
) a
)
There is no guarantee that the rows returned by a query using ROW_NUMBER() will be ordered exactly the same with each execution unless the following conditions are true:
Values of the partitioned column are unique. [partitions are parent-child, like a boss has 3 employees][ignore]
Values of the ORDER BY columns are unique. [if column 1 is unique, row_number should be stable]
Combinations of values of the partition column and ORDER BY columns are unique. [if you need 10 columns in your order by to get unique... go for it to make row_number stable]"
There is a secondary issue here, with this being a view. Order By's don't always work in views (long-time sql bug). Ignoring the row_number() for a second:
create view MyView as
(
select top 10000000 [or top 99.9999999 Percent] col1
from (
Select col1 From Table1
Union All
Select col1 From Table2
) a order by col1
)
Using "row_number() over ( order by col1) as ID" is very expensive.
This way is much more efficient in cost:
Create View [MyView] as
(
Select ID = isnull(cast(newid() as varchar(40)), '')
, col1
, col2
, col3
From Table1
UnionAll
Select ID = isnull(cast(newid() as varchar(40)), '')
, col1
, col2
, col3
From Table2
)
use ROW_NUMBER() with "order by (select null)" this will be less expensive and will get your result.
Create View [MyView] as
SELECT ROW_NUMBER() over (order by (select null)) as id, *
FROM(
Select col1, col2, col3 From Table1
Union All
Select col1, col2, col3 From Table2 ) R
GO

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.