postgresql How to share cte among different tables in plain sql? - postgresql

Say select id from some_expensive_query is the cte I want to share. Currently I write two sql in a transaction:
with t as (select id from some_expensive_query) select * from t1 join t on t.id =t1.id;
with t as (select id from some_expensive_query) select * from t2 join t on t.id =t2.id;
As you can see, the cte is executed twice but I want something like:
t = select id from some_expensive_query;
select * from t1 join t on t.id =t1.id;
select * from t2 join t on t.id =t2.id;
for portability, I don't want to use pgsql or functions, anyway to solve this?

Why don't you use union all ?
with t as (select id from some_expensive_query)
select * from t1 join t on t.id =t1.id
union all
select * from t2 join t on t.id =t2.id;

Related

How do I join two tables with same column names keeping values from one the tables

I have these two tables:
Table1
-------
id|a|b|c|d|
1 |0|1|0|6|
and
Table2
-------
id|a|c|
1 |3|2|
How do I join these two tables keeping the values from table2 but also the columns from table1, so that the table would look like this afterwards:
TableJoined
-------
id|a|b|c|d|
1 |3|1|2|6|
Tried with
SELECT * FROM Table2 a JOIN Table1 b WHERE a.id = b.id;
hoping that the first table mentioned would be the overrider
Or I guess you could do:
SELECT b.id, a.a, b.b, a.c, b.d FROM Table2 a JOIN Table1 b WHERE a.id = b.id;
You can achieve that by qualifying the * with the table alias:
SELECT a.* FROM Table2 a JOIN Table1 b WHERE a.id = b.id;
But you should never use * in a SELECT list except in ad-hoc queries. (The exception is count(*) which is OK to use).

CloudKit - How to perform Not Exists query?

I want to perform a database query in CloudKit like in SQL:
SELECT *
FROM table1 t1
WHERE NOT EXISTS
(SELECT *
FROM table2 t2
WHERE t1.userid = t2.userid)
Do you know how to do that?
Try
SELECT *
FROM table1 t1
WHERE t1.userid NOT IN(
SELECT t2.userid
FROM table2 t2);
or
SELECT t1.userid
FROM table1 t1
MINUS
SELECT t2.userid
FROM table2 t2;

How to optimize SELECT DISTINCT when using multiple Joins?

I have read that using cte's you can speed up a select distinct up to 100 times. Link to the website . They have this following example:
USE tempdb;
GO
DROP TABLE dbo.Test;
GO
CREATE TABLE
dbo.Test
(
data INTEGER NOT NULL,
);
GO
CREATE CLUSTERED INDEX c ON dbo.Test (data);
GO
-- Lots of duplicated values
INSERT dbo.Test WITH (TABLOCK)
(data)
SELECT TOP (5000000)
ROW_NUMBER() OVER (ORDER BY (SELECT 0)) / 117329
FROM master.sys.columns C1,
master.sys.columns C2,
master.sys.columns C3;
GO
WITH RecursiveCTE
AS (
SELECT data = MIN(T.data)
FROM dbo.Test T
UNION ALL
SELECT R.data
FROM (
-- A cunning way to use TOP in the recursive part of a CTE :)
SELECT T.data,
rn = ROW_NUMBER() OVER (ORDER BY T.data)
FROM dbo.Test T
JOIN RecursiveCTE R
ON R.data < T.data
) R
WHERE R.rn = 1
)
SELECT *
FROM RecursiveCTE
OPTION (MAXRECURSION 0);
How would one apply this to a query that has multiple joins? For example i am trying to run this query found below, however it takes roughly two and a half minutes. How would I optimize this accordingly?
SELECT DISTINCT x.code
From jpa
INNER JOIN jp ON jpa.ID=jp.ID
INNER JOIN jd ON (jd.ID=jp.ID And jd.JID=3)
INNER JOIN l ON jpa.ID=l.ID AND l.CID=3
INNER JOIN fa ON fa.ID=jpa.ID
INNER JOIN x ON fa.ID=x.ID
1) GROUP BY on every column worked faster for me.
2) If you have duplicates in some of the tables then you can also pre select that and join from that as an inner query.
3) Generally you can nest join if you expect that this join will limit data.
SQL join format - nested inner joins

tsql join 2 tables with duplicate records in the second table

I have 2 tables.
Table 1:
Id Name
1 John
2 Mike
3 Sam
Table 2:
Name Data
John Data1
John Data1
John Data1
Mike Data2
Mike Data2
Sam Data3
If I write
select Table2.Name, Table2.Data
from Table1
inner join Table2 on Table1.Name= Table2.Name
I get all the duplicate data.
I would like to be able to retrieve something like:
John Data1
Mike Data2
Sam Data3
SELECT DISTINCT NAME
, DATA
FROM Table2
WHERE NAME IN (SELECT NAME
FROM Table1)
There are a few different options here...
There are two ways to do that.
You can use distinct clause:
select distinct t2.Name, t2.Data
from Table1 t1
inner join Table2 t2 on t1.Name= t2.Name
Here is link to MSDN.
You can use group by :
select t2.Name, t2.Data
from Table1 t1
inner join Table2 t2 on t1.Name= t2.Name
group by t2.Name, t2.Data
Here is link to MSDN.
I prefer second solution, because I always can add grouping functions.
Note:
In both queries I used aliases (t1,t2). It's more readable.
You can use CTE for this and apply a row_number()
;with cte as
(
select t1.name, t2.data,
row_number() over(partition by t1.id order by t1.id) rn
from table1 t1
inner join table2 t2
on t1.name = t2.name
)
select *
from cte
where rn = 1
Or a non-CTE version:
select *
from
(
select t1.name, t2.data,
row_number() over(partition by t1.id order by t1.id) rn
from table1 t1
inner join table2 t2
on t1.name = t2.name
) x
where rn = 1
see SQL Fiddle with Demo
Are you looking for something like:
select Table2.Name, Table2.Data, count(*) from Table1
inner join Table2 on Table1.Name= Table2.Name
group by Table2.Name, Table2.Data;

How to use "as" to set alias for joined tables in oracle 10

I wrote this, and it is wrong syntax, help me fix it, I want 'T' to be an alias of the result of the two inner joins.
select T.id
from table1
inner join table2 on table1.x = table2.y
inner join table3 on table3.z = table1.w as T;
You cannot use aliases to name the "entire" join, you can, however, put aliases on individual tables of the join:
select t1.id
from table1 t1
inner join table2 t2 on t1.x = t2.y
inner join table3 t3 on t3.z = t1.w
In the projection, you will have to use the alias of the table, which defines the id column you are going to select.
You can't directly name the result of a join. One option is to use a subquery:
select T.id
from (
select *
from table1
inner join table2 on table1.x = table2.y
inner join table3 on table3.z = table1.w
) T
Another option is subquery factoring:
with T as (
select *
from table1
inner join table2 on table1.x = table2.y
inner join table3 on table3.z = table1.w
)
select T.id
from T