I'm a beginner in sql and need some help using the left join (or alternate) function inthe following:
I have 2 tables:
1) Client
2) Server
Client has 2 columns (country and clientname) which is not present in Server. I want to join / copy these two columns into the Server table using the unique identifier column 'ClientID' present in both tables to match and join. How would I go about doing this and does anything recommend an easier way? I currently don't have physical access to a DB so I can't really test out any queries, so any help is appreciated!
Thank you
Are you looking for this?
SELECT s.*, c.country, c.clientname
FROM server s LEFT JOIN client c
ON s.clientid = c.clientid
Here is SQLFiddle demo.
For better understanding of JOINs see A Visual Explanation of SQL Joins
Related
I am totally new to MS Access, so please be kind if my requests might look nonsense.
I have a database with two tables: tblHerbs and tblSeasons.
Two fields in tblHerbs refer to tblSeasons and I don't know how to set the relation between these two tables, besides building a simple query that allows me to select everything from tblHerbs (and show it on a Report).
Any kind of help would be highly appreciated.
You need alias
select t.Season1, s1.name, t.Season2, s2.name
from ((tblHerbs t
inner join tblSeasons s1 on s1.name= t.Season1 )
inner join tblSeasons s2 on s2.name= t.Season2)
so i wanted to join two tables and i wrote:vehicle and policy
Select registrationNo, policyNumber, Make
Where registrationNo.vehicle = Registration.No.policy
Is this correct?
There are some type of joins, depending on your needs.
If you are using MySQL, find more information here: https://dev.mysql.com/doc/refman/5.7/en/join.html
A possible solution for you (without more information) could be:
SELECT * FROM vehicle LEFT JOIN policy ON vehicle.id=policy.id;
I have three tables
I would like to request all persons, where the companyTypeID is for example '2'. How can I query that?
You could use the in operator:
SELECT *
FROM persons
WHERE CompanyId IN (SELECT CompanyId
FROM company
WHERE CompanyTypeId = 2)
Do an INNER JOIN (left or right joins are functionally similar, the only difference is which side of the equation is honoured). Nested queries / subqueries are extremely expensive if they become dependent in nature—even though that's not the scenario in your case—and I do not recommend using them for large tables.
SELECT t1.*
FROM Persons AS t1
LEFT JOIN Company AS t2 ON
t2.companyTypeID = t1.CompanyID
To ensure that you are using an index for joining, you should create indexes on the companyTypeID and CompanyID columns of each table. Prepend EXPLAIN EXTENDED to the query above to verify that the indexes are indeed being used.
You need to use SQL statement JOIN. It's all about mathematical sets!
A Graphic (and superficial) explanation about JOINs statement under mathematical sets approach:
https://www.google.com.br/imgres?imgurl=http%3A%2F%2Fi.imgur.com%2FhhRDO4d.png&imgrefurl=https%3A%2F%2Fwww.reddit.com%2Fr%2Fprogramming%2Fcomments%2F1xlqeu%2Fsql_joins_explained_xpost_rsql%2F&docid=q4Ank7XVw8j7DM&tbnid=f-L_7a3HkxW_3M%3A&w=1000&h=740&client=ubuntu&bih=878&biw=1745&ved=0ahUKEwj2oaer5evPAhUBFZAKHe4nAdAQMwgdKAEwAQ&iact=mrc&uact=8#h=740&w=1000
SQL for your problem(If I got this):
SELECT * FROM Persons p LEFT JOIN Company c ON c.ID = p.companyID
LEFT JOIN CompanyType ct ON ct.ID = c.companyTypeID
WHERE c.id = 2;
Why 'LEFT JOIN'? Checkout the the link about set approach explanation above!
The second 'LEFT JOIN' is just to bring the description of companyType table.
The "*" in statement is didatic! You must not use this in production for the good of performance. Therefore, you must to replace the '*' with all the fields you need. For example, "CONCAT(p.firstname,CONCAT(" ",p.lastname)) as PersonName, c.name CompanyName,..." or something like that. I suppose you're using MySQL
Hope I've helped!
Perform an SQL join:
Joins are quicker than the subquery, in the other post:
SELECT Persons.firstname AS first name
FROM Persons
JOIN Company ON company.ID == Persons.CompanyID
WHERE Company.companyTypeID == 2
Although you will need to select all he fields you want, using alias to simplify the names
Lets say I have the following query:
SELECT occurs.*, events.*
FROM occurs
INNER JOIN events ON (events.event_id = occurs.event_id)
WHERE event.event_state = 'visible'
Another way to do the same query and get the same results would be:
SELECT occurs.*, events.*
FROM occurs
INNER JOIN events ON (events.event_id = occurs.event_id
AND event.event_state = 'visible')
My question. Is there a real difference? Is one way faster than the other? Why would I choose one way over the other?
For an INNER JOIN, there's no conceptual difference between putting a condition in ON and in WHERE. It's a common practice to use ON for conditions that connect a key in one table to a foreign key in another table, such as your event_id, so that other people maintaining your code can see how the tables relate.
If you suspect that your database engine is mis-optimizing a query plan, you can try it both ways. Make sure to time the query several times to isolate the effect of caching, and make sure to run ANALYZE TABLE occurs and ANALYZE TABLE events to provide more info to the optimizer about the distribution of keys. If you do find a difference, have the database engine EXPLAIN the query plans it generates. If there's a gross mis-optimization, you can create an Oracle account and file a feature request against MySQL to optimize a particular query better.
But for a LEFT JOIN, there's a big difference. A LEFT JOIN is often used to add details from a separate table if the details exist or return the rows without details if they do not. This query will return result rows with NULL values for b.* if no row of b matches both conditions:
SELECT a.*, b.*
FROM a
LEFT JOIN b
ON (condition_one
AND condition_two)
WHERE condition_three
Whereas this one will completely omit results that do not match condition_two:
SELECT a.*, b.*
FROM a
LEFT JOIN b ON some_condition
WHERE condition_two
AND condition_three
Code in this answer is dual licensed: CC BY-SA 3.0 or the MIT License as published by OSI.
I have a query in MS-Access like this:
select DISTINCTROW companies.* from companies, contacts, companies left join contacts on contacts.com_uid = companies.com_uid (This is the ms-access form of a standard "left-join")
[Companies] and [contacts] are linked views on a sql-server 2008, ODBC driver is "SQL server native client 10.0". Both views looks like "select * from [companies] where deleted = 0" and "select * from [contacts] where delete = 0"
The result is wrong since companies are show as many contacts there are.
If the Views are stored on a SQL2000 and linked with the ODBC-driver "SQL Server" everything is fine: All the companies are shown exactly once.
Are there any solutions to get the result with DISTINCTROW again?
I'm surprised it executes that query at all. You're specifying the table "contacts" twice.
Your LEFT JOIN should return every row from "companies". Since you're not retrieving any columns from contacts, I'm pretty sure your query is equivalent to
SELECT *
FROM companies
as long as "companies" means what it does in ordinary language.
If that turns out not to be the case, you can hand the burden off to SQL Server either by creating a view in SQL Server, or by creating a passthrough query in Access. A passthrough query will have to be written in your server's dialect of SQL (SQL Server 2008 dialect of SQL).
Your revision, reproduced below, does nothing to change my earlier comments.
select DISTINCTROW companies.*
from companies, contacts, companies
left join contacts on contacts.com_uid = companies.com_uid
(This is the ms-access form of a standard "left-join")
That's not Access's form of a left join. Access won't allow this:
from companies, contacts, companies
left join contacts
because you're now specifying both tables twice.
Based on your edit, I'd say the query you're trying to write is still equivalent to
SELECT *
FROM companies
What do you get if you run that?
Let's stop talking about the syntax of a left-join in ms-access. Fact is that if the linked tables are views on sql-server 2000:
create view [companies] as
select * from [TabCompanies] where deleted = 0
and
create view [contacts] as
select * from [TabContcts] where deleted = 0
These views are ODBC-linked-tables in a ms-access 2003/2007 mdb.
The questions shows up in ms-access on a query like
select distinctrow [companies].* from [companies] left join [contacts] on [companies].com_uid = contacts.com_uid] where [contacts].[function] like 'C*'
(lets forget that alternative syntax and look on the result assuming that the left join works without an error or syntaxerror)
This DISTINCTROW is a ms-access feature and not know in sql-server and for my point of view the result is the same like DISTINCT but works also even if there are columns with datatype of images par example.
All together we expect by now the same like Catcall in his answer said "select * from companies" BUT IT IS NOT, why?
This is only an excerpt of the whole query and may be makes no sense for production but it shows the changed behaviour wehn sql2008 is connected.
The purpose of DISTINCTROW is to make editable the two sides of an N:1 join. With a Cartesian product (from companies, contacts, companies), the result cannot be editable, so DISTINCTROW has no advantage over DISTINCT.
Secondly, no matter what you say, it is not possible to have the same table twice in a FROM clause without an alias. The SQL you've posted could not have worked in any version of Access.
The only way I can possible imagine there's any sense in what you've posted is if you've omitted a WHERE clause.
EDIT BASED ON COMMENTS:
This should work:
SELECT DISTINCT companies.*
FROM companies INNER JOIN contacts ON companies.com_uid = contacts.com_uid
WHERE contacts.function LIKE "C*"
First off, I'd assume a normal N:1 relationship between contacdts and companies (i.e., many contact records are linked to any single company record), so with both tables in the FROM clause, you do need a DISTINCT to return a single row for each company.
Secondly, if you place criteria on the table on the many side of the JOIN, there's no reason to attempt to use a LEFT JOIN, as it won't change the records returned (use a LEFT JOIN when you want to return records regardless of whether or not there are records in the table on the many side of the JOIN). So, an INNER JOIN is going to do the job for you, and be more efficient (outer JOINs are just slower, even with criteria).