I am developing a sample windowsform app, which print reports when the user perform a double click in a row of a data grid view.
After troubleshooting some issue with query ecc, I run in a strange from statement which i've never seen.
Below the statement:
SELECT some_tables
FROM table1 table2 inner join table3 table4 on table2.id = table4.id
This statament is the result of a working query which I caught by using SQL profiler, I need to do this because the previous query didn't retrive the right data.
I've already searched the statement on the internet but without success, so in details what it do?
EDIT: I just saw #Larnu said the same thing I did, she is correct^^
What is happening here is the use of an alias, you can read about them here
FROM table1 table2 inner join table3 table4 on table2.id = table4.id
Is using an alias, where table2 is an alias for table1, and table4 is an alias for table3.
You can make the association that:
table2 = table1
table4 = table3
So that statement could also be written:
FROM table1 inner join table3 on table1.id = table3.id
table2 and table4 are aliases (usually shorter names) for the tables table1 and table3.
The inner join means that the records of the two tables are combined pairwise where table2.id must match table4.id.
Example:
table1
id description
-- -----------
1 Apple
2 Orange
3 Pear
table2
id name
-- -----
1 Peter
1 Sue
2 Marc
The query
SELECT
a.id, a.description, b.name
FROM
table1 a
INNER JOIN table2 b
ON a.id = b.id
Result
id description name
-- ----------- ----
1 Apple Peter
1 Apple Sue
2 Orange Marc
Related
I want to export a report in csv format from data that is contained in three different tables. I made a temporary table using the data from one table. My idea was then to use two JOINs to add in the data from the others, and then once the temporary table is filled out using COPY to export it and then delete the table.
Table1
-id (primary key)
-data1
-data2 (foreign key for Table2)
-data3
Table2
-id (primary key, Table1.data2 matches with this)
-data1 (foreign key for Table3)
-data2
Table3
-id (primary key, Table2.data1 matches with this)
-data1
The final unified table would have the following:
-id
-table1.data1
-table1.data2
-table1.data3
-table2.data1
-table2.data2
-table3.data1
First I made a temporary table using the information I wanted from table1, as this table has most of the information for the report.
Database=# create temp table temp_table as select id,data1,data2,data3 from table1;
SELECT 71
Using a select showed the data in this new table.
Next, I tried to use a JOIN to join all the data from Table2 to Table1, using the matching keys.
Database=# select * from table2 join temp_table on table2.id = temp_table.data2;
The resulting console output showed success! It listed this combined table as expected. However, when using a select all statement on the temp table, it only showed the initial data fields it was populated with. It did not include the data from Table2 like I was shown in the console output. A quick select all on table2 showed no change, so I didn't flip flop them and accidentally copy temp_table to table2. I think I might be misunderstanding either the JOIN commands, or how they are properly used.
I am still very new to SQL, and I have made an honest attempt at searching for solutions but nothing I found seemed to be relevant or helpful. Any help would be greatly appreciated, and as I want to learn any explanations are also greatly appreciated :)
many thanks
edit:
sample data
table1
id formalID linkid textdata
3 3 3 [blank]
9 13 9 [blank]
1 1 10 [blank]
35 38 [blank] “sample text”
table2
id nameid typetext
3 3 [blank]
9 9 “Alpha”
10 1 “Beta”
table3
id nameText
3 “Sweet”
9 “Sour”
1 “Tangy”
end result:
formalID nameText typeText textdata
3 “Sweet” [blank] [blank]
13 “Sour” “Alpha” [blank]
1 “Tangy” “Beta” [blank]
38 [blank] [blank] “sample text”
linkid would be table1.data2 from my initial post, that is the same as table2.id and nameid would be table2.data1 which is the same as table3.id
It is possible for entries to not have data in the other two, when this is the case they contain entries in 'textdata' but should still be included in the end result.
The following should output all your data:
SELECT t1.data1, t1.data3, t2.data2 as t2_data, t3.data1 as t3_data
FROM Table1 t1 LEFT JOIN Table2 t2 ON t1.data2 = t2.id
LEFT JOIN Table3 t3 ON t2.data1 = t3.id
You pretty much have it solved, you just need to set up your join statements. Your code should look like the following:
SELECT
table1.id,
table1.data1,
table1.data2,
table1.data3,
table2.data1,
table2.data2,
table3.data1
FROM table1
LEFT JOIN table2 ON table1.data2 = table2.id
LEFT JOIN table3 ON table2.data1 = table3.id
You can also add conditions to the individual JOIN statements if needed. Example:
LEFT JOIN table2 ON table1.data2 = table2.id
AND <condition>
LEFT JOIN table3 ON table2.data1 = table3.id
AND <condition>
Also, you don't need to use a temp table for this query.
With the given sample data
SELECT t1.formalid,
t3.nametext,
t2.typetext,
t1.textdata
FROM table1 t1
LEFT JOIN table2 t2
ON t2.nameid = t1.id
LEFT JOIN table2 t3
ON t3.id = t1.id;
would get you the expected result. The LEFT JOIN makes sure every row from the table left to the operator is retained in the result even if there's no matching row in the table right of it.
To export it put the query in parenthesis (important!) and let it follow the copy command:
COPY (SELECT t1.formalid,
t3.nametext,
t2.typetext,
t1.textdata
FROM table1 t1
LEFT JOIN table2 t2
ON t2.nameid = t1.id
LEFT JOIN table2 t3
ON t3.id = t1.id)
TO '<path to the output file>'
WITH FORMAT csv;
Change <path to the output file> to the path of the file you want the output to go into. The path must be on the server machine, i.e. the machine the Postgres service runs on, not the client machine and it must be write accessible for the user the Postgres service runs under.
There are some more options, that let you toggle headers, define the encoding, etc., have a look at the documentation to learn more about them.
You can use the COPY command with a query directly. No need for a TEMP TABLE.
Note: The directory in which you intend to export to must allow write privileges to the postgres user.
Try the following:
COPY
( SELECT t1.id
, t1.data1
, t1.data2
, t1.data3
, t2.data1
, t2.data2
, t3.data1
FROM table1 t1
LEFT JOIN table2 t2 ON t1.d2 = t2.id
LEFT JOIN table3 t3 ON t2.d1 = t3.id
)
TO 'path/to/filename'
WITH FORMAT CSV
I have been searching for this scenario that has come across my desk, I have been searching reference sites but haven't had luck creating the correct SQL statement to complete this task.
Here is the PSEUDO code for the scenario.
UPDATE TABLE1
SET TABLE1.ID = TABLE1.From_ID,
TABLE1.VALUE = 'ALL'
WHERE TABLE1.From_ID = TABLE2.ID
AND TABLE2.NAME = 'TEST'
Basically I need to update two columns in TABLE1 only if the id from TABLE1 matches the ID's in the TABLE2 and the description column in TABLE2 equals to a string value the caveat is that TABL1 columns can't be change only if there is a correlation between the ID's from TABLE1 and TABLE2 and in TABLE2 that ID correlates to description column for a specific string value. Below is table structure and end result I'm trying to get too.
TABLE1:
FIELD_ID CONDITIONAL_VALUE FROM_FIELDID
--------------------------------------------
1 TEST 3
7 TEST 4
5 ANY 7
TABLE2:
FIELD_ID Description
----------------------------------------------
3 BLUE
4 BLUE
7 RED
In Transact-SQL (SQL Server's dialect of SQL), you need a FROM clause in your SQL if you specify more than the table you're trying to update.
update
TABLE1.ID
set
TABLE1.ID = TABLE1.From_ID ,
TABLE1.VALUE = 'ALL'
from
TABLE1,
TABLE2
where
TABLE1.From_ID = TABLE2.ID
AND TABLE2.NAME = ''TEST
You need to join data from TABLE1 to TABLE2
UPDATE t1
SET t1.ID = t1.From_ID
,t1.VALUE = 'ALL'
FROM Table1 AS t1
JOIN table2 AS t2
ON t1.From_ID = t2.ID
AND t2.NAME = 'TEST't1
Can anyone suggest me how to compare two database tables in sql server and return the rows in the second table which are not in the first table. The primary key in both the tables is not the same. For instance, the tables are as follows.
Table1
ID Name DoB
1 John Doe 20/03/2012
2 Joe Bloggs 31/12/2011
Table2
ID Name DoB
11 John Doe 20/03/2012
21 Joe Bloggs 31/12/2011
31 James Anderson 14/04/2010
The sql query should compare only the Name and DoB in both tables and return
31 James Anderson 14/04/2010
Thanks.
Pretty simple, use a LEFT OUTER JOIN to return everything from Table2 even if there isn't a match in Table1, then limit that down to only rows that don't have a match:
SELECT Table2.ID, Table2.Name, Table2.DoB
FROM Table2
LEFT OUTER JOIN Table1 ON Table2.Name = Table1.Name AND Table2.DoB = Table1.DoB
WHERE Table1.ID IS NULL
Look into the use of SQL EXCEPT
SELECT Name, DOB
FROM Table1
EXCEPT
SELECT Name, DOB
FROM Table2
http://msdn.microsoft.com/en-us/library/ms188055.aspx
You want a LEFT OUTER JOIN. http://en.wikipedia.org/wiki/Join_(SQL)#Left_outer_join
This type of JOIN will return all records of the 'left' table (the table in the FROM clause in this example) even if there are no matching records in the joined table.
SELECT Table2.ID, Table2.Name, Table2.DoB
FROM Table2
LEFT OUTER JOIN Table1 ON Table1.Name = Table2.Name AND Table1.DoB = Table2.DoB
WHERE Table1.ID IS NULL
Note that you can substitue LEFT OUTER JOIN for LEFT JOIN. It's a short cut that most DBMSs use.
use CHECKSUM () function in sql server
select T1.* from Table1 T1 join Table2 T2
on CHECKSUM(T1.Name,T1.DOB)!= CHECKSUM(T2.Name,T2.DOB)
Details
This SQL statement compares two tables without having to specify column names.
SELECT 'Table1' AS Tbl, binary_checksum(*) AS chksum, * FROM Table1
WHERE binary_checksum(*) NOT IN (SELECT binary_checksum(*) FROM Table2)
UNION
SELECT 'Table2' AS Tbl, binary_checksum(*) AS chksum, * FROM Table2
WHERE binary_checksum(*) NOT IN (SELECT binary_checksum(*) FROM Table1)
ORDER BY <optional_column_names>, Tbl
The output will display any rows that are different and rows that are in Table1, but not Table2 and vice versa.
I have two tables:
Table 1
id, name1
Table 2
id, name2a, name2b
Table 2's column names name2a, and name2b are references to table 1's id. I need to create a query that pulls both the names out of table 1 based on the id's used in Table 2.
Therefore, if Table one contained:
1 Peter
2 Paul
And Table 2 contained:
1 1 2
2 2 2
Then a select statement should give me:
Peter Paul
Paul Paul
I've gone around the bend trying to build this SQL and the best I came up with was:
SELECT table1.name AS 'name', table1.name AS 'Other name'
FROM table1, table2
WHERE table1.id = table2.name2a
Which only gives me the name2a column correctly.
Any help appreciated! I guess I need to do a join, but I'm really struggling...
Start with your 2nd table and join TWICE to table 1 (different aliases respectively), then get the name field from each aliased Table1 entry.
select
T2.ID,
TJ1.Name1 as FirstName,
TJ2.Name1 as SecondName
from
Table2 t2
join Table1 TJ1
on t2.Name2a = TJ1.ID
join Table1 TJ2
on t2.Name2b = TJ2.ID
select foo.*, t1.x, t2.y
join t1 on t1.id = foo.a
join t1 as t2 on t2.id = foo.b
If there's a chance that col a or col b is null, use a left join.
Have you tried using an INNER JOIN?
SELECT table1.name AS 'name', table1.name AS 'Other name'
FROM table1 INNER JOIN table2 ON table1.id = table2.name2a;
Sorry if I'm no help, not that great at SQL myself hehe.
Your problem is that you need to reference table1 twice: once for the plain table1.name and again to look up what table2 is pointing at. You can join one table in multiple times if you give them aliases:
SELECT t1.name1, o.name1
FROM table1 t1
JOIN table2 t2 ON t1.id = t2.name2a
JOIN table1 o ON t2.name2b = o.id -- And JOIN back to table1 to get the name1
For example, there are two tables:
create table Table1 (id int, Name varchar (10))
create table Table2 (id int, Name varchar (10))
Table1 data as follows:
Id Name
-------------
1 A
2 B
Table2 data as follows:
Id Name
-------------
1 A
2 B
3 C
If I execute both below mentioned SQL statements, both outputs will be the same:
select *
from Table1
left join Table2 on Table1.id = Table2.id
select *
from Table2
right join Table1 on Table1.id = Table2.id
Please explain the difference between left and right join in the above SQL statements.
Select * from Table1 left join Table2 ...
and
Select * from Table2 right join Table1 ...
are indeed completely interchangeable. Try however Table2 left join Table1 (or its identical pair, Table1 right join Table2) to see a difference. This query should give you more rows, since Table2 contains a row with an id which is not present in Table1.
Table from which you are taking data is 'LEFT'.
Table you are joining is 'RIGHT'.
LEFT JOIN: Take all items from left table AND (only) matching items from right table.
RIGHT JOIN: Take all items from right table AND (only) matching items from left table.
So:
Select * from Table1 left join Table2 on Table1.id = Table2.id
gives:
Id Name
-------------
1 A
2 B
but:
Select * from Table1 right join Table2 on Table1.id = Table2.id
gives:
Id Name
-------------
1 A
2 B
3 C
you were right joining table with less rows on table with more rows
AND
again, left joining table with less rows on table with more rows
Try:
If Table1.Rows.Count > Table2.Rows.Count Then
' Left Join
Else
' Right Join
End If
You seem to be asking, "If I can rewrite a RIGHT OUTER JOIN using LEFT OUTER JOIN syntax then why have a RIGHT OUTER JOIN syntax at all?" I think the answer to this question is, because the designers of the language didn't want to place such a restriction on users (and I think they would have been criticized if they did), which would force users to change the order of tables in the FROM clause in some circumstances when merely changing the join type.
select fields
from tableA --left
left join tableB --right
on tableA.key = tableB.key
The table in the from in this example tableA, is on the left side of relation.
tableA <- tableB
[left]------[right]
So if you want to take all rows from the left table (tableA), even if there are no matches in the right table (tableB), you'll use the "left join".
And if you want to take all rows from the right table (tableB), even if there are no matches in the left table (tableA), you will use the right join.
Thus, the following query is equivalent to that used above.
select fields
from tableB
right join tableA on tableB.key = tableA.key
Your two statements are equivalent.
Most people only use LEFT JOIN since it seems more intuitive, and it's universal syntax - I don't think all RDBMS support RIGHT JOIN.
I feel we may require AND condition in where clause of last figure of Outer Excluding JOIN so that we get the desired result of A Union B Minus A Interaction B.
I feel query needs to be updated to
SELECT <select_list>
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.Key = B.Key
WHERE A.Key IS NULL AND B.Key IS NULL
If we use OR , then we will get all the results of A Union B
select *
from Table1
left join Table2 on Table1.id = Table2.id
In the first query Left join compares left-sided table table1 to right-sided table table2.
In Which all the properties of table1 will be shown, whereas in table2 only those properties will be shown in which condition get true.
select *
from Table2
right join Table1 on Table1.id = Table2.id
In the first query Right join compares right-sided table table1 to left-sided table table2.
In Which all the properties of table1 will be shown, whereas in table2 only those properties will be shown in which condition get true.
Both queries will give the same result because the order of table declaration in query are different like you are declaring table1 and table2 in left and right respectively in first left join query, and also declaring table1 and table2 in right and left respectively in second right join query.
This is the reason why you are getting the same result in both queries. So if you want different result then execute this two queries respectively,
select *
from Table1
left join Table2 on Table1.id = Table2.id
select *
from Table1
right join Table2 on Table1.id = Table2.id
Select * from Table1 t1 Left Join Table2 t2 on t1.id=t2.id
By definition: Left Join selects all columns mentioned with the "select" keyword from Table 1 and the columns from Table 2 which matches the criteria after the "on" keyword.
Similarly,By definition: Right Join selects all columns mentioned with the "select" keyword from Table 2 and the columns from Table 1 which matches the criteria after the "on" keyword.
Referring to your question, id's in both the tables are compared with all the columns needed to be thrown in the output. So, ids 1 and 2 are common in the both the tables and as a result in the result you will have four columns with id and name columns from first and second tables in order.
*select *
from Table1
left join Table2 on Table1.id = Table2.id
The above expression,it takes all the records (rows) from table 1 and columns, with matching id's from table 1 and table 2, from table 2.
select *
from Table2
right join Table1 on Table1.id = Table2.id**
Similarly from the above expression,it takes all the records (rows) from table 1 and columns, with matching id's from table 1 and table 2, from table 2. (remember, this is a right join so all the columns from table2 and not from table1 will be considered).