How to join select with itself in postgresql? - sql

How to join select with itself in postgresql?
SELECT *
FROM (
SELECT src, dst FROM records
) as t1
JOIN t1 t2
USING(src)
UPDATE:
my table doesn't exists already and I create a table with "SELECT" and I want join this selected table with itself.

Use a Common Table Expressiom:
with t1 as
(
SELECT src, dst FROM records
)
SELECT *
FROM t1 JOIN t1 t2
USING(src)

You should fix the question. But one obvious problem is that you cannot re-use a table alias to define another table in the same from clause where it is defined. Hence, I think you want:
SELECT r1.src, r1.dst, r2.src, r2.dst
FROM records r1 JOIN
records r2
USING (src);

Related

Joining tables using concat column

So I have two tables I want to join using SQL.
Since they did not have a common column I used
SELECT NEW_ID = CONCAT ('0',table1.ID)
Now that I have the new column with matching data in both tables, how do I join both tables? Is there any way to use the NEW_ID column as a temporary column so that I do not have to alter table 1?
In your case, suitable. of course in terms of performance it is not the best solution ( compare fields with diffrent types)
Select *
From Table1 As t1 inner join Table2 as t2
ON t1.ID = CAST(t2.ID AS INT)
Different ways, here's one:
;WITH CTE AS
(
SELECT NEW_ID = CONCAT ('0',table1.ID) FROM TableA
)
SELECT * FROM CTE AS C INNER JOIN TableB AS B ON C.New_ID = B.ID
You Can Just give the Concrete Expression in the Join.You Don't have to add a new Column For that. Like this
SELECT
*
FROM Table1 A
INNER JOIN Table2 B
ON RIGHT('00'+A.Id,2) = RIGHT('00'+B.Id,2)

WHERE + NOT EXIST + 2 Columns

I have a query, that should return all records in T1 that not linked to records in T2:
SELECT DISTINCT fldID, fldValue FROM T1
WHERE NOT EXISTS
(
SELECT T1.fldID, T1.fldValue
FROM T2
JOIN T1 ON T2.fldID = T1.fldPtr
)
But it returns empty set -- should be one record.
If I use query like this (clause on one field):
SELECT DISTINCT fldID FROM T1
WHERE fldID NOT IN
(
SELECT T1.fldID
FROM T2
JOIN T1 ON T2.fldID = T1.fldPtr
)
It returns correct result.
But the SQL Server do not support syntax
WHERE ( fldID, flrValue ) NOT IN ....
Help me please to figure out how to compose query that will check several columns?
Thanks!
You can also use EXCEPT for this:
SELECT DISTINCT fldID, fldValue FROM T1
EXCEPT
SELECT T1.fldID, T1.fldValue
FROM T2
JOIN T1 ON T2.fldID = T1.fldPtr
A more efficient and elegant query that will work with every database is:
SELECT T1.*
FROM T1
LEFT JOIN T2
ON T2.fldID = T1.fldPtr
AND T2.flrValue = T1.flrValue
WHERE T2.fldID IS NULL
The LEFT JOIN attempts to match using both criteria, then the WHERE clause filters the joins, and only non-joins have NULL values for the LEFT JOINed table.
This approach is IMHO pretty much the industry standard for finding non-matches. It is usually more efficient than a NOT EXIstS(), although several databases optimize a NOT EXISTS() to this query anyway.
Use both those columns if sub-query join:
SELECT DISTINCT fldID, fldValue FROM T1
WHERE NOT EXISTS
(
SELECT *
FROM T2
JOIN T1 ON T2.fldID = T1.fldPtr
AND T1.fldValue = T2.flrValue
)
Something like (I think, as I'm not sure I 100% understand your question):
SELECT DISTINCT fldID FROM T1
WHERE fldID NOT IN
(
SELECT T1.fldID
FROM T2
JOIN T1 ON T2.fldID = T1.fldPtr
WHERE T2.flrValue = T1.flrValue
)
If you have the same structure in both tables you can use the EXCEPT operator http://technet.microsoft.com/en-us/library/ms188055.aspx
In a more general case, you have to to use left join and find null elements in second table.
try the below Query.
select DISTINCT fldID
from Table1
WHERE cast(fldID as varchar(100))+'~'+cast(flrValue as varchar)
NOT IN (select cast(fldID as varchar(100))+'~'+cast(flrValue as varchar) from table2)
This is more easy query. It returns all T1.fldID that not linked to records in T2
SELECT DISTINCT T1.fldID
FROM T1
LEFT JOIN T2 ON T2.fldID = T1.fldPtr
WHERE T2.fldID IS NULL
Using IN to exclude a large number of values is terrible for performance. Try the following:
SELECT T1.*
FROM T1
LEFT JOIN T2 ON T2.fldID = T1.fldPtr AND T1.fldValue = T2.fldvalue
WHERE T2.fldID IS NULL
(from my comment:) you do not have to reference t1 again in the subquery. Doing so would cause a logic of the form select all the records from t1 that don't exist in t1 ..., which is always empty, just like select all blue balls that are not blue, or select all odd numbers that are even ...
The first query should be:
SELECT DISTINCT fldID, fldValue
FROM T1
WHERE NOT EXISTS (
SELECT * FROM T2
WHERE T2.fldID = T1.fldPtr
);
And: in your original query, the subquery is uncorrelated: The t1 in the subquery shadows the t1 in the main query, making the subquery not referring any table or alias from the main query: it returns either True (some row exists) or False, the result being totally uncorrelated to the rows in the main query. (yet another good reason to use aliases instead of real table names in your queries)

In SQL Server, How to join two table having different column name and different data row?

Suppose I have two tables T1 & T2. I want resulting output table as O1 with help of a SQL query
T1 {SName}
T2 {VName}
O1 {SName, VName}
It seems like you want a cross join of the two tables to include all combinations of rows in T1 and T2. Try this:
Select SName, VName From T1 Inner Join T2 On 1=1
The number of rows you will get is the product of the number of rows in T1 and T2 each.
if you're not joining on anything and want a table of all possible combinations:
select SName, VName
into O1
from T1 cross join T2
if you have a column to join on:
select SName, VName
into O1
from T1 inner join T2 on T1.col = T2.col
Select record from T1 and T2 based on filtering criteria and then insert record in table O1 , use below query to create table O1 and inserting those records.
INSERT INTO O1(SNAME, VNAME)
SELECT(T1.SNAME, T2.VNAME)
From T1 Inner Join T2 On 1=1 //i.e WHERE T1.id=T2.T1_id
use WHERE to filter records
there are several ways of doing it.one easy way is:
select T1.SName,T2.VName from T1,T2;
i don't know if i am right, you can use cross join.
if you have two tables Players and GameScores then
SELECT* INTO O1 FROM GameScores CROSS JOIN Players will return all records where each row from the first table is combined with each row from the second table. Which also mean CROSS JOIN returns the Cartesian product of the sets of rows from the joined tables.
to get the above result as
T1 {SName}
T2 {VName}
O1 {SName, VName}
(SELECT * FROM T1,T2) as O1;
will definitely work if both the table have single value if not then you can select the
Particular column like T1.SName,T2.VName

How can I reference a single table multiple times in the same query?

Sometimes I need to treat the same table as two separate tables. What is the solution?
You can reference, just be sure to use a table alias
select a.EmployeeName,b.EmployeeName as Manager
from Employees A
join Employees B on a.Mgr_id=B.Id
Use an alias like a variable name in your SQL:
select
A.Id,
A.Name,
B.Id as SpouseId,
B.Name as SpouseName
from
People A
join People B on A.Spouse = B.id
Use an alias:
SELECT t1.col1, t2.col3
FROM tbl t1
INNER JOIN tbl t2
ON t1.col1 = t2.col2
Alias is the most obvious solution
SELECT * FROM x1 AS x,y1 AS y
However if the table is the result of a query a common table expressions is quite usefull
;WITH ctx AS
( select * from z)
SELECT y.* FROM ctx AS c1,ctx AS c2
A third solution -- suitable when your query lasts a long time -- is temporary tables:
SELECT *
INTO #monkey
FROM chimpanzee
SELECT * FROM #monkey m1,#monkey m2
DROP TABLE #MONKEY
Note a common table expression is only available for one query (the query directly after it), and temporary tables last for the whole batch.

What is the standard SQL Query to retrieve the intersection of tables?

Selecting the union:
select * from table1
union
select * from table1_backup
What is the query to select the intersection?
In SQL Server intersect
select * from table1
intersect
select * from table1_backup
SELECT *
FROM table1
WHERE EXISTS
(SELECT *
FROM table1_backup
WHERE table1.pk = table1_backup.pk)
works
For questions like this, I tend to go back to this visual resource:
A Visual Explanation of SQL Joins
inner join i think:
suppose T1 and T2 have the same structure:
select T1.* from
T1 inner join T2 on T1.pkField = T2.pkField
"intersect" is also part of standard SQL.
Inner join gives a different answer.
here is a solution for mySQL:
CREATE TABLE table1(
id INT(10),
fk_id INT(10),
PRIMARY KEY (id, fk_id),
FOREIGN KEY table1(id) REFERENCES another_table(id),
FOREIGN KEY table1(fk_id) REFERENCES other_table(id)
);
SELECT table1.* FROM table1 as t0
INNER JOIN table1 as a ON (t0.id = a.id and fk_id=1)
INNER JOIN table1 as b ON (t0.id = b.id and fk_id=2)
INNER JOIN table1 as c ON (t0.id = c.id and fk_id=3)
ORDER BY table1.id;
Basically you have an table of mathematical subsets (ie. 1={1, 2 ,3}, 2={3, 4, 2}, ... , n={1, 4, 7}) with an attribute id, which is the set number, and fk_ id, which references a PRIMARY KEY of a table of elements, the superset (meaning possible values for the numbers in the curly braces). For those not mathematically inclined, let's pretend you have a table, 'other_ table', which is a list of items, and another table, 'another_ table', which is a list of transaction numbers, and both tables form a many-to-many relationship, thus producing 'table1'. now let's pretend you wanted to know the id's in 'another_ table' which had items 1, 2, and 3. that's the query to do it.
An intersect on two identical tables a and b can be done in this manner:
SELECT a.id, a.name
FROM a INNER JOIN b
USING (id, name)
subqueries?! really?
to get the intersection of table1 and table2:
SELECT * FROM table1, table2 WHERE table1.pk=table2.pk;
select distinct * from (select * from table1 union select * from table1_backup)