I hope that i can explain it right, because i'm not a native english speaker.
I have 2 tables- Document and Vehicle.
As you can see in the SELECT query, the columns Id(Vehicle) and VehicleId(Document) are common.
The columns SeriePolita,NumarPolita,d.Status are from the Document table and v.CascoCategorieVehicul,v.NumarInmatriculare from the Vehicle table.
This code was written some time ago ( is working - no problem in the syntax ) by someone who left the company and my colleagues are using this code and weren't able to explain it to me.
My question is -
Can some explain or put a link with some info, for the Vehicle v on v.Id = d.VehicleId. What is the meanning of vehicle v and how is using d.Status different that Status, without the d.
select
SeriePolita,
NumarPolita,
d.Status,
v.CascoCategorieVehicul,
v.NumarInmatriculare
from Document d
inner join Vehicle v on v.Id = d.VehicleId
where EndDate>'2015-06-30' and d.Class='CASCO' and Status in ('Polita', 'Anulat')
Vehicle v is a reference to the Vehicle table by the alias v. The reason for doing this is so you don't have to type, for instance inner join Vehicle on Vehicle.Id = Document.VehicleId - it's shortened and more concise and you can refer to the alias in the select and where clause.
Now suppose that there is a Status column in both tables, without referring to it by either table name or alias, you would get an ambiguous column error as the DB engine would not know which table column you are referring to. If there is only only Status column then your query will run fine, although it is unclear which table the column actually belongs to!
See more on this in the documentation:
Using Table Aliases
the code you have can be rewritten as follows:
select
d.SeriePolita,
d.NumarPolita,
d.Status,
v.CascoCategorieVehicul,
v.NumarInmatriculare
from Document AS d
inner join Vehicle AS v on v.Id = d.VehicleId
where EndDate>'2015-06-30'
and d.Class='CASCO'
and Status in ('Polita', 'Anulat');
mind the AS keyword between Document and d: that is the keyword to tell the system that the object Document from now on will be 'known as' d.
it is a keyword that is not mandatory, may be omitted safely as in your code.
on msdn you can find details about table aliasing.
„Vehicle v” is a shorthand for „Vehicle as v”
Here the “v” is just an alias for the table “Vehicle” so you can just access columns of the table using this alias.
v.NumarInmatriculare has excactly same semantic meaning that Vehicle.NumarInmatriculare
Regards
Jan
Here Vehicle is a table and v is a table alias.
see this for more info https://technet.microsoft.com/en-us/library/ms187455%28v=sql.105%29.aspx
http://www.w3schools.com/sql/sql_alias.asp
Vehicle v on v.Id = d.VehicleId
v.Id means Id column from Vehicle table and d.VehicleId means VehicleId from document table
Can some explain or put a link with some info, for the Vehicle v on
v.Id = d.VehicleId. What is the meanning of vehicle v and how is using
d.Status different that Status, without the d.
TLDR: vehicle v means that v is an alias for vehicle and anywhere we use v.columnname would mean vehicle.columnname
Detail explanation:
Often in SQL queries we create an alias for table names, so that we can refer to them using that alias instead of original table name. There are multtiple reasons to do so. Let me introduce to two common ones.
When resolving ambiguity in column name Like when you want to join two tables say Employee and Spouse and both have same columns ID and name. And you want to select both names in your output. So query syntax is like
SELECT name,name FROM Employee JOIN Spouse on ID=ID
This query can not execute as both ID columns and name columns are in both tables and cannot be resolved to a single table correctly. Correct way to write query is
SELECT Employee.name,Spouse.name FROM Employee JOIN Spouse on Employee.ID=Spouse.ID
Note that though this query executes, still the output will be like
name | name
________________
John | Jane
Margaret | Dave
Still you cannot guess spouse or Employee from output. Good way is to use Alias like this
SELECT Employee.name as EmployeeName,Spouse.name as SpouseName FROM Employee JOIN Spouse on Employee.ID=Spouse.ID
which gives you output like
EmployeeName | SpouseName
___________________________
John | Jane
Margaret | Dave
This syntax columnname as aliasname allows us to use aliasname instead of original column name, clearly any ambiguity or renaming column so that expected output makes sense especially in case of join
Now if the example had both spouse and employees stored in same table say Person, so we had create self join
SELECT Person.name as EmployeeName,Person.name as SpouseName FROM person JOIN person on person.ID=person.ID
now again we have the same problem as both person.ID and Person.name repeat even though they are qualified by their table names, as there are two table names person and person (left and right side of JOIN).
In this case to resolve ambiguity we need to give alias to table names and refer to column using those alias like below:
SELECT Employee.name as EmployeeName,Spouse.name as SpouseName FROM person as Employee JOIN person as Spouse on Employee.ID=Spouse.ID
note that as keyword can be omitted. Most DBAs do not use it. So this below query is same as before.
SELECT Employee.name EmployeeName,Spouse.name SpouseName FROM person Employee JOIN person Spouse on Employee.ID=Spouse.ID
When you need to use a shorter, less typo prone name in query
Now wouldn't it be better that instead of writing long names again and again we can use shorter alias. Well we can. So both queries below produce same output.
This is same as
SELECT Employee.name as EmployeeName,Spouse.name as SpouseName FROM Employee JOIN Spouse on Employee.ID=Spouse.ID
this
SELECT E.name EmployeeName,S.name SpouseName FROM Employee E JOIN Spouse S on E.ID=S.ID
Related
Currently I have a staff table with columns:
Staff_Id, first_name, Surname.
My second table is:
Id, management_role.
When I link the tables each staff member gets added to every management role. So for example a person in first table called Jim is added three times as manager, supervisor, intern and this happens for every staff.
Some things to consider that are your ID columns are primary keys for their respective tables. If not are every value in the column is unique? Also are ids not
From your description you might be using a cross join here. The thing you need is inner join so it joins the matching id's together.
So you can do
SELECT *
FROM staff_table as st
INNER JOIN management_table as mt
ON st.Staff_Id = mt.ID
I have two tables on PostgreSQL, namely: employees and employers.
There is data in each of these tables.
Columns in employees: employee_id, employee_name, employer_id.
Columns in employers: employer_id, employer_name.
I want to display all employee_name's that don't have an associating employer_name.
I used the below query:
SELECT DISTINCT a.employee_name, b.employer_name
FROM employees a
NATURAL JOIN employers b
WHERE a.employee_name LIKE 'Jack';
NB!
I have also tried adding in the below to my query:
COALESCE(b.employer_name, '') = ''
Problem:
If there is no record in the employer table containing the associating employee_id value, the query returns nothing all. I am assuming this is because there is nothing for the two tables to join on?... But I would like to at least find all employees that don't have an employer. I would ideally like the employer_name value in my result to either return: blank/''/NULL.
Your assistance is greatly appreciated.
select employees.employee_name ,employers.employer_name
from employees
left join employers
on employees.employee_id = employees.employee_id
where employers.employer_name is NULL
Use a LEFT JOIN:
SELECT a.employee_name,
COALESCE(b.employer_name, 'NA') AS employer_name
FROM employees a
LEFT JOIN employers b
ON a.employer_id = b.employer_id
WHERE b.employer_id IS NULL
Your current query has several problems, first of which is that you are using a NATURAL JOIN, which should behave link an INNER JOIN, discarding employee records which do not match to any employer. Instead, by using LEFT JOIN, we can retain all employee records, regardless of whether or not they have an employer. The WHERE clause checks for NULL in the joined table, with NULL indicating that the employee did not match to any employer.
Your table name employees table is a little odd, IMO. There is a design 'rule of thumb' that says a table models either an entity or the relationship between entities but not both. To demonstrate this oddness, consider the relational operation is
employees MINUS employers
...which suggests something is off.
Another symptom of this design problem is that the employer_id in the employees table must have some kind of placeholder to represent the predicate employee has no employer, possibly a null (and nulls are to be avoided, IMO).
I suggest you fix this design by introducing a third table to model the relationship between an employee and their employer. Herein lies another design problem: shouldn't this new table be named employees? In other words, isn't the very definition of an employee a person who has an employer?
Consider this design instead:
People: person_id, person_name
Employers: employer_id, employer_name
Employees: employer_id, person_id
To find the names of people who are not employees in pseudo-relational notation:
People MINUS Employees { person_name }
SQL is quite a bit more verbose:
SELECT DISTINCT person_name
FROM People
NATURAL JOIN
( SELECT person_id FROM People
EXCEPT
SELECT person_id FROM Employees ) t;
Note your original query needlessly uses range variables a and b. One of the benefits of NATURAL JOIN is the elminiation of duplicate column names. Range variables with NATURAL JOIN always looks odd to me!
So I have three tables: companies, addresses and company_address.
For optimization reasons I need to copy city column from addresses table to companies table. Relation between companies and addresses is many to one (as many companies can occupy same address). They are connected through company_address table, consisting of address_id and company_id columns.
I found this solution for case without intermediate table: How to copy one column of a table into another table's column in PostgreSQL comparing same ID
Trying to modify query I came up with:
UPDATE company SET company.city=foo.city
FROM (
SELECT company_address.company_id, company_address.address_id, address.city
FROM address LEFT JOIN company_address
ON address.id=company_address.address_id
) foo
WHERE company.id=foo.company_id;
but it gives error:
ERROR: column "company" of relation "company" does not exist
I cant figure out what is going on. I'll be grateful for any ideas.
You don't need a subquery for that. Also, refer in the SET clause to your table columns without preceding with table name.
I believe that since your WHERE condition includes joined table, it should be INNER JOIN instead of a LEFT JOIN.
UPDATE company c
SET city = a.city
FROM address a
INNER JOIN company_address ca ON a.id = ca.address_id
WHERE c.id = ca.company_id
Note how using aliases for table names shortens the code and makes it readable at the very first glance.
You're right syntactically, you just don't need the table name at the beginning of the update statement:
UPDATE company SET city=foo.city
FROM (
SELECT company_address.company_id, company_address.address_id, address.city
FROM address LEFT JOIN company_address
ON address.id=company_address.address_id
) foo
WHERE company.id=foo.company_id;
I'm having an issue creating a query. Here are the specifics.
There are 2 tables company_career and company_people.
People contains person information (Name, Address, etc) and Career contains historical career information (job_title, department, etc.)
People is linked to Career by job_ref_id.
Direct_Report_id lies in the career table and contains a unique id that correlates to job_ref_id.
Example: job_ref_id = '1' results in direct_report_id ='A'. I then use the value produced from direct-report_id (i.e., 'A') and query the job_ref_id = 'A' and this produces the employee name. Since it produces the employee name (which is actually the manager) I need to know how I would query this to present this as the manager name.
I think I know what you are looking for, you just need to use joins and aliases. For example:
SELECT
cp.name AS [EmployeeName],
cp.address AS [EmployeeAddress],
cc.job_title AS [EmployeeTitle],
cc.department AS [EmployeeDept],
m.name AS [ManagerName]
FROM company_people cp
LEFT JOIN company_career cc ON cc.job_ref_id = cp.job_ref_id
LEFT JOIN company_people m ON m.job_ref_id = cc.direct_report_id
I am trying to use a second SELECT to get some ID, then use that ID in a second SELECT and I have no idea how.
SELECT Employee.Name
FROM Emplyee, Employment
WHERE x = Employment.DistributionID
(SELECT Distribution.DistributionID FROM Distribution
WHERE Distribution.Location = 'California') AS x
This post got long, but here is a short "tip"
While the syntax of my select is bad, the logic is not. I need that "x" somehow. Thus the second select is the most important. Then I have to use that "x" within the first select. I just don't know how
/Tip
This is the only thing I could imagine, I'm very new at Sql, I think I need a book before practicing, but now that I've started I'd like to finish my small program.
EDIT:
Ok I looked up joins, still don't get it
SELECT Employee.Name
FROM Emplyee, Employment
WHERE x = Employment.DistributionID
LEFT JOIN Distribution ON
(SELECT Distribution.DistributionID FROM Distribution
WHERE Distribution.Location = 'California') AS x
Get error msg at AS and Left
I use name to find ID from upper red, I use the ID I find FROM upper red in lower table. Then I match the ID I find with Green. I use Green ID to find corresponding Name
I have California as output data from C#. I want to use California to find the DistributionID. I use the DistributionID to find the EmployeeID. I use EmployeeID to find Name
My logic:
Parameter: Distribution.Name (from C#)
Find DistributionID that has Distribution.Name
Look in Employment WHERE given DistributionID
reveals Employees that I am looking for (BY ID)
Use that ID to find Name
return Name
Tables:
NOTE: In this example picture the Employee repeats because of the select, they are in fact singular
In "Locatie" (middle table) is Location, I get location (again) from C#, I use California as an example. I need to find the ID first and foremost!
Sory they are not in english, but here are the create tables:
Try this:
SELECT angajati.Nume
FROM angajati
JOIN angajari ON angajati.AngajatID = angajari.AngajatID
JOIN distribuire ON angajari.distribuireid = distribuire.distribuireid
WHERE distribuire.locatie = 'california'
As you have a table mapping employees to their distribution locations, you just need to join that one in the middle to create the mapping. You can use variables if you like for the WHERE clause so that you can call this as a stored procedure or whatever you need from the output of your C# code.
Try this solution:
DECLARE #pLocatie VARCHAR(40)='Alba'; -- p=parameter
SELECT a.AngajatID, a.Nume
FROM Angajati a
JOIN Angajari j ON a.AngajatID=j.AngajatID
JOIN Distribuire d ON j.DistribuireID=d.DistribuireID
WHERE d.Locatie=#pLocatie
You should add an unique key on Angajari table (Employment) thus:
ALTER TABLE Angajari
ADD CONSTRAINT IUN_Angajari_AngajatID_DistribuireID UNIQUE (AngajatUD, DistribuireID);
This will prevent duplicated (AngajatID, DistribuireID).
I don't know how you are connecting Emplyee(sic?) and Employment, but you want to use a join to connect two tables and in the join specify how the tables are related. Joins usually look best when they have aliases so you don't have to repeat the entire table name. The following query will get you all the information from both Employment and Distribution tables where the distribution location is equal to california. You can join employee to employment to get name as well.
SELECT *
FROM Employment e
JOIN Distribution d on d.DistributionID = e.DistributionID
WHERE d.Location = 'California'
This will return the contents of both tables. To select particular records use the alias.[Col_Name] separated by a comma in the select statement, like d.DistributionID to return the DistributionID from the Distribution Table