Creating view in phpmyadmin - sql

When i try to create view like this CREATE VIEW data2tables AS
SELECT * FROM Employees e INNER JOIN Computers c ON e.id = c.id WHERE e.name = 'Georgi' AND c.department = 'Sales'
it gives me error saying that #1060 - Duplicate column name 'id',and i have no idea how to fix it or why does the error occur.
CREATE VIEW data2tables AS
SELECT * FROM Employees e INNER JOIN Computers c
ON e.id = c.id
WHERE e.name = 'Georgi' AND c.department = 'Sales';
#1060 - Duplicate column name 'id'

Your table Employees and the table Computers both have a column named id.
When you say SELECT * FROM Employees e INNER JOIN Computers c... you are basically saying give me every column 'Employees' AND 'Computers' so you are getting a duplicate of id (and any other column in there that may be the same name).
With a VIEW you want to select a defined set of results so I would recommend explicitly specifying the columns you want from both tables.
If you require id from both tables I would recommend giving the joined table (Computers) id column an alias...something like this:
CREATE VIEW data2tables AS
SELECT e.id, e.fieldA, e.fieldN, c.id as ComputersId, c.fieldA, c.fieldN
FROM Employees e
INNER JOIN Computers c ON e.id = c.id
WHERE e.name = 'Georgi' AND c.department = 'Sales';
That method of aliasing will also apply to any other cross-over column names you encounter.

try to specify columns for Computer's table.
CREATE VIEW data2tables AS
SELECT e.*, c.[column_name].... FROM Employees e INNER JOIN Computers c
ON e.id = c.id
WHERE e.name = 'Georgi' AND c.department = 'Sales';

Related

SQL Joins and Corelated subqueries with column data

I am facing an issue in terms of understanding the joins. Lets say for an example we have two tables employee and sales and now I have a query where we have sales of an employee using the id of the employee
select e.employeename
,s.city
,SUM(s.sales)
from employee e
left join (select sales,eid from sales) s on s.eid = e.id
group by 1,2
I'd like to understand why s.city wasn't showing up? and also would like to understand what is this concept called? Is it co related sub queries on Joins? Please help me down over here.
select
e.employeename
,s.city
,SUM(s.sales)
from employee e
left join (select sales,eid,city from sales) s on s.eid = e.id
group by 1,2
in the left join above you have to add city as well. The query Imagine select sales,eid,city from sales is a table itself and then from this table you are selecting city (your second column s.city) this will run error as your table doesn't have a city column yet.
It is much easier to use CTE (common table expressions than CTE's) You can also do the above question as
select
e.employeename
,s.city
,SUM(s.sales)
from employee e
left join sales as s
on e.id = s.id
group by 1,2
here I have added e.id = s.id instead of s.id = e.id it is better to reference the key of the main table first.
you could use CTE (although used when you have to do a lot of referencing but you can see how it works):
With staging as (
select
e.employeename
,s.city
,s.sales
from employee e
left join sales as s
on e.id = s.id
),
sales_stats as (
select
staging.employeename,
staging.city,
sum(staging.sales)
from staging
group by 1,2
#here you will select from staging again consider staging as a separate table so you will have to have all the columns in the staging that you want to use further. Also you will have to reference columns using staging.x
)
select * from sales_stats
-- here you could have combined the steps but I wanted to show you how cte works, Hope this works for you

Joining two tables with specific columns

I am new to SQL, I know this is really basic but I really do not know how to do it!
I am joining two tables, each tables lets say has 5 columns, joining them will give me 10 columns in total which I really do not want. What I want is to select specific columns from both of the tables so that they only show after the join. (I want to reduce my joining result to specific columns only)
SELECT * FROM tbEmployees
JOIN tbSupervisor
ON tbEmployees.ID = tbSupervisor.SupervisorID
The syntax above will give me all columns which I don't want. I just want EmpName, Address from the tblEmployees table and Name, Address, project from the tbSupervisor table
I know this step:
SELECT EmpName, Address FROM tbEmployees
JOIN tbSupervisor
ON tbEmployees.ID = tbSupervisor.SupervisorID
but I am not sure about the supervisor table.
I am using SQL Server.
This is what you need:
Select e.EmpName, e.Address, s.Name, S.Address, s.Project
From tbEmployees e
JOIN tbSupervisor s on e.id = SupervisorID
You can read about this on W3Schools for more info.
You can get columns from specific tables, either by their full name or using an alias:
SELECT E.EmpName, E.Address, S.Name, S.Address, S.Project
FROM tbEmployees E
INNER JOIN tbSupervisor S ON E.ID = S.SupervisorID
You can use the table name as part of the column specification:
SELECT tbEmployees.EmpName, tbEmployeesAddress, tbSupervisor.Name,
tbSupervisor.Address, tbSupervisor.project
FROM tbEmployees
JOIN tbSupervisor
ON tbEmployees.ID = tbSupervisor.SupervisorID
SELECT employees.EmpName, employees.Address AS employeer address,
supervisor.Name, supervisor.Address AS supervisor address,supervisor.project
FROM tbEmployees
AS employees
JOIN tbSupervisor
AS supervisor
ON
employees.ID = supervisor.SupervisorID
You need to learn about aliases. They will make your queries more maintainable. Also, you should always use aliases when referencing columns, so your query is clear about what it is doing:
SELECT e.EmpName, e.Address, s.name, s.address as SupervisorAddress
FROM tbEmployees e JOIN
tbSupervisor s
ON e.ID = s.SupervisorID;
Note that I also renamed the second address so its name is unique.
Specify the table name and field name in your selection
SELECT tbEmployees.EmpName,
tbEmployees.Address,
tbSupervisor.[column name]
FROM tbEmployees
JOIN tbSupervisor ON tbEmployees.ID = tbSupervisor.SupervisorID
SELECT product_report.*,
product.pgroup
FROM `product_report`
INNER JOIN product
ON product_report.product_id = product.id
WHERE product.pgroup = '5'
ORDER BY product.id DESC

How would I do this conditional join in MS SQL?

I searched around for conditional joins, but it seems like they're trying to do something different that what I'm trying. I'll simplify the problem a bit for the question.
I have three tables: Users, Clients, and Employees.
The Users table has two columns, AssociatedID and UserType.
UserType is either "Client" or "Employee," and AssociatedID is a corresponding ID in either the Clients or the Employees table.
The problem is, Clients and Employees both use integers for IDs, so each table could have the same ID for something completely different (as opposed to GUIDs, which would avoid this problem).
What I want is a query that will look at a row in Users and say if UserType is Employee, then JOIN AssociatedID on the Employees table's ID, and if UserType is Client, then JOIN AssocaitedID on the Clients table's ID. So if Clients and Employees both have a Name column, I could get all of the names that go with each User, regardless of if they're a Client or an Employee. I'm using SQL Server 2008 R2 if that makes a difference here.
Try this:
SELECT
COALESCE(c.Name, e.Name) AssociatedName,
...
FROM Users u
LEFT JOIN Clients c ON u.AssociatedID = c.ClientId
AND u.UserType = 'Client'
LEFT JOIN Employees e ON u.AssociatedID = e.EmployeeId
AND u.UserType = 'Employee';
SQL Fiddle demo
Or: As #Tikkes pointed out, you can do this with UNION like this:
SELECT c.Name AssociatedName
FROM Users u
INNER JOIN Clients c ON u.AssociatedID = c.ClientId
AND u.UserType = 'Client'
UNION ALL
SELECT e.Name FROM Users u
INNER JOIN Employees e ON u.AssociatedID = e.EmployeeId
AND u.UserType = 'Employee';
Updated SQL Fiddle Demo
Update: For this you have to use the CASE expression like this:
SELECT
u.AssociatedID,
CASE u.UserType
WHEN 'Client' THEN c.Name
ELSE e.Name
END AS AssociationName
FROM Users u
LEFT JOIN Clients c ON u.AssociatedID = c.ClientId
LEFT JOIN Employees e ON u.AssociatedID = e.EmployeeId;
Updated SQL Fiddle Demo using CASE
Same Senario: I have CustomerExt have SoldTo and ShipTo Code,
and if ShipTo column has value then use ShipToName in table ShipTo otherwise use CustomerName in Customer table
Select COALESCE(B.CustomerName, C.ShiptoName) as CustomerName
FROM CustomerExt A
left join Customer B ON A.SoldTo = B.CustomerCode
AND isnull(A.ShipTo,'') =''
left join ShipTo C ON A.ShipTo = C.ShipToCode
AND isnull(A.ShipTo,'') <>''

Calculate Percentage Of Certified Managers

I asked a similar question a few weeks ago, but now the requirements have changed.
Considering the following tables:
http://www.maroisconsulting.com/Temp/query.png
I need to create a query that returns the percentages of employees who are managers (Titles.IsManager) and who have a date in the Certified field (Employees.Certified). The results need to be grouped by the Group each store is in.
So far I have this:
SELECT d.GroupId,
Sum(d.cert_complete) AS SumOfcert_complete,
Count(d.cert_complete) AS CountOfcert_complete
FROM (SELECT DISTINCT
s.GroupId,
e.EmployeeID,
IIf(e.Certified Is Null,0,1) AS cert_complete
FROM
((Stores AS s
INNER JOIN EmployeeStores AS es ON s.StoreId = es.StoreId)
INNER JOIN Employees AS e ON es.EmployeeId = e.EmployeeID)
INNER JOIN Titles AS t ON e.TitleId = t.TitleId
) AS d
WHERE t.IsManager
GROUP BY d.GroupId;
And then this
SELECT q.GroupId,
(SumOfcert_complete/CountOfcert_complete)*100 AS percent_certified,
Groups.GroupName
FROM qryGroupCert_base AS q
INNER JOIN Groups ON q.GroupId = Groups.GroupId;
You can see in the first query where I added the Titles table.
1) I get prompted for the IsManager, although I don't know why
2) The results coming back are not different than before I added the IsManager
Anyone see what's wrong here?
Many thanks
Within your first query, you have this subquery which includes Titles aliased as "t":
(SELECT DISTINCT
s.GroupId,
e.EmployeeID,
IIf(e.Certified Is Null,0,1) AS cert_complete
FROM
((Stores AS s
INNER JOIN EmployeeStores AS es ON s.StoreId = es.StoreId)
INNER JOIN Employees AS e ON es.EmployeeId = e.EmployeeID)
INNER JOIN Titles AS t ON e.TitleId = t.TitleId
) AS d
Then, after the definition of the subquery, you have this WHERE clause:
WHERE t.IsManager
The problem is the "t" alias and IsManager column only exist within the the subquery --> they are unknown to the outer (parent) query. In cases where the Access database engine encounters something it doesn't recognize as an object name, function, literal value, or SQL keyword, it thinks that something must be a parameter ... so pops up the input box asking you to provide a value for the (IsManager) parameter.
I think you should move the WHERE clause inside the subquery definition.
SELECT d.GroupId,
Sum(d.cert_complete) AS SumOfcert_complete,
Count(d.cert_complete) AS CountOfcert_complete
FROM [SELECT DISTINCT
s.GroupId,
e.EmployeeID,
IIf(e.Certified Is Null,0,1) AS cert_complete
FROM
((Stores AS s
INNER JOIN EmployeeStores AS es ON s.StoreId = es.StoreId)
INNER JOIN Employees AS e ON es.EmployeeId = e.EmployeeID)
INNER JOIN Titles AS t ON e.TitleId = t.TitleId
WHERE t.IsManager = True
]. AS d
GROUP BY d.GroupId;
Perhaps you need to supply a criteria for t.IsManager, such as t.IsManager = TRUE. If the where clause doesn't have a value to set it equal to, Access probably isn't resolving it to the actual column, but thinks it's a query parameter.

How do I join 3 tables using mysql

I have the following tables:
TABLE: companies c
FIELDS: id, name, description
TABLE: departments d
FIELDS: id, name, description
TABLE employees e
FIELDS: id, company_id, department_id, name
I'm trying to get a list of all employees for company 1 and also get the department name (d.name) into the results of the row.
Here's my original query:
SELECT e.*, c.name as company
FROM employees e, companies c
WHERE e.company_id=c.id AND e.company_id=1;
What should I add to this query to get the department name (d.name) to appear in each row of the query? Also... e.department_id may be equal to 0 in some cases since there are no departments for a specific company.
Thanks for the help everyone!
SELECT e.id, e.name, e.department_id, c.name, d.name
FROM employees AS e
LEFT JOIN departments AS d ON e.department_id = d.id
LEFT JOIN companies AS c ON e.company_id = c.id
WHERE e.company_id = 1;
Generally you can mix-match joins in any order, as long as any columns/tables you require in a join have already been joined previously. In this case, you're slurping up data from two separate tables that are related via the employees data, and neither of them are co-dependent, so you can order the two LEFT JOIN lines in any order.
As well, with a LEFT join, you get all rows from the table on the "left" side of the join (in this case, the employees table) and matching rows (if any) from the right table (companies/departments). If there's no matching rows in either companies or departments, then any columns coming from those tables will be NULL in the result set.