Can anyone tell me why I am getting this error?
SELECT C.ClientID, C.ClientCode, C.FullName, E.FullName AS EmployeeName
FROM ClientID C, EmployeeInfo E, tmntClientTreatmentInfo T, CliniciansClients CC
JOIN CliniciansClients
ON CliniciansClients.ClientID = ClientID.ClientID
JOIN ClientID
ON ClientID.ClientID = CliniciansClients.ClientID
JOIN EmployeeInfo
ON EmployeeInfo.EmployeeID = CliniciansClients.EmployeeID
JOIN tmntClientTreatmentInfo
ON tmntClientTreatmentInfo.ClientID = ClientID.ClientID
The multi-part identifier "ClientID.ClientID" could not be bound. // Line 6
Tony, there are lots of ways to do selects with joins and many different types of joins. But I would recommend you start by doing something basic, making sure it works, then if it's not performant or brings back duplicate data, start optimizing the joins or work on your normalization / denormalization. After a while, you'll get the hang of it. Until then, I quickly set up a postgres instance in Docker, created the tables you referenced, and this query should work:
SELECT C.ClientID, C.ClientCode, C.FullName, E.FullName AS EmployeeName
FROM ClientID C
JOIN CliniciansClients AS CC
ON CC.ClientID = C.ClientID
JOIN EmployeeInfo AS E
ON E.EmployeeID = CC.EmployeeID
JOIN tmntClientTreatmentInfo as leonardo
ON leonardo.ClientID = C.ClientID
Related
I have 2 tables - Client, Jobs,
Client - clientID,clientName,clientCity
Bricklayers - jobNum, clientID, startDate
Now I need to query the database to list me all clients in 3 cities (Charlotte, Raleigh, Wilmington) and if they have a job on the Bricklayers table also list their jobNum(s) and startDate
I'm completely unsure what approach to take to this problem as I've never needed a query like this. I know I need a join and tried an inner join on the clientID in both columns but kept receiving syntax errors.
Try this
SELECT c.clientID, c.clientName, b.jobNum, b.startDate
FROM Client c
INNER JOIN Bricklayers b ON c.clientID = b.clientID
WHERE c.clientCity IN ('Charlotte','Raleigh','Wilmington');
I'm a beginner trying to learn and practice SQL with tables based on this schema:
EMPLOYEE - ID, Name
ASSIGNMENT - ID, Country, Start, End
The primary keys are Employee.ID and all four columns shown for ASSIGNMENT; and ASSIGNMENT.ID is a reference to EMPLOYEE.ID. The domain of start and end is in years.
Problem: I'm trying to write a query that will display all the employees (by name) where they were assigned to an assignment in the USA directly after they had completed an assignment in Canada.
This is my current attempt, which fails to compute. I believe I am heading in the correct direction but there are syntactical mistakes.
SELECT
E.Name
FROM
EMPLOYEE E
INNER JOIN
ASSIGNMENT A ON E.ID = A.ID
WHERE
(SELECT End FROM ASSIGNMENT
WHERE Country = 'Canada') = (SELECT Start FROM ASSIGNMENT
WHERE COUNTRY = 'USA')
GROUP BY
E.Name;
Any critique to benefit my understanding of my misconceptions are welcome. My errors are coming from the combination of the subqueries in the WHERE clause
At most one record can be returned by this subquery.
Perhaps someone can show me another way to compute this?
This query is being tested in MS Access since I found it easy to build a database and relationships quickly.
Instead of subqueries use another join and add constraints to the join conditions:
SELECT
E.Name
FROM
EMPLOYEE E
INNER JOIN
ASSIGNMENT A ON ( E.ID = A.ID
AND A.Country = 'Canada' )
INNER JOIN
ASSIGNMENT B ON ( E.ID = B.ID
AND B.Country = 'USA'
AND B.Start = A.End )
GROUP BY
E.Name;
Update
The OP reported an error from MS Access complaining about the composite join condition for the above version. However, you may safely move inner join conditions to the where clause. The interim resultsets will grow, though, since the product of the tables is produced first with less constraints and filtered thereafter (A good query optimizer might avoid the unnecessary generation of records, but I do not know about the capabilities of MS Access in this regard).
SELECT
E.Name
FROM
EMPLOYEE E
INNER JOIN
ASSIGNMENT A ON ( E.ID = A.ID )
INNER JOIN
ASSIGNMENT B ON ( E.ID = B.ID )
WHERE
A.Country = 'Canada'
AND B.Country = 'USA'
AND B.Start = A.End
GROUP BY
E.Name;
I have a query that pulls user id and various events associated with each user. Since a user can have multiple events, I need the first event ever associated with each user.
Add a constraint to any answers - our server is delicate and has a hard time handling subqueries.
Here is the initial query:
select
c.id as eid,
c.created as contact_created,
e.event_time,
cs.name as initial_event_type
from bm_emails.cid378 c
inner join bm_sets.event378 e on e.eid = c.id
inner join bm_config.classes cs on cs.id = e.class_id
group by
eid, initial_class
order by eid desc
Which produces results that look like this:
eid contact_created event_time initial_event_type
283916 2015-03-09 10:56:22 2015-03-09 10:57:21 Hot
283916 2015-03-09 10:56:22 2015-03-09 10:56:22 Warm
283914 2015-03-09 10:17:32 2015-03-09 10:17:32 Warm
283912 2015-03-09 10:11:03 2015-03-09 10:11:03 Warm
283910 2015-03-09 09:54:15 2015-03-09 09:54:15 Hot
So in this case user 283916 has been returned twice in the results. What I'd like is to return only one result for this user, the one where initial_event_type says "warm" since that happened first (min event_time).
Here is what I tied. Presumably it would work on a more powerful server but ours just can't handle sub queries - it takes a long time and our developer gets upset whenever I leave queries running.
select
c.id as eid,
c.created as contact_created,
e.event_time,
cs.name as initial_class
from bm_emails.cid378 c
inner join bm_sets.event378 e on e.eid = c.id
inner join bm_config.classes cs on cs.id = e.class_id
where concat(e.eid, e.event_time) in ( select concat(eid, min(event_time))
from bm_sets.event378
group by eid)
group by
eid, initial_class
order by eid desc
Is it possible to pull this data without use of sub queries? I've seen people do multiple joins on the same table before and I think that may be the right path but, like our server, my brain is not powerful enough to figure out how to start on that path.
Any other more efficient solutions?
** Following answer by below, here is outcome of explain statement:
Is it possible to pull this data without use of sub queries
The fact that you use a subquery is not the problem. The problem is cause by filtering on concat(eid, min(event_time) in your subquery since there is likely not an index on this expression, requiring a table scan. A better option would be a filtered subquery:
select
c.id as eid,
c.created as contact_created,
e.event_time,
cs.name as initial_class
from bm_emails.cid378 c
inner join bm_sets.event378 e on e.eid = c.id
inner join bm_config.classes cs on cs.id = e.class_id
where e.event_time = ( select min(event_time)
from bm_sets.event378
WHERE eid = e.eid))
order by eid desc
I have this schema :
When I want to display the Attend table, instead of DoctorId and PatientId, Employee Name And Patient Name display.
Like this:
id
Patient name
Doctor Name [== Employee name]
Start
End
First way is to use an inner join :
select
a.Id, p.Name, a.Name, a.Start, a.End
from
Patient as p
inner join
(select
e.Name, at.Id, at.Start, at.End, at.PatientId
from
Attend as at
INNER JOIN
Employee as e on at.DoctorId = e.Id) as a on p.Id = a.PatientId
Second way is to use a function or stored procedure - send in the id and get back name
select
a.Id,
FindDoctor(a.DoctorId) as Doctor,
FindPatient(a.PatientId) as Patient,
a.Start, a.EndTime
from
Attend AS a
Which is the better? Which is the optimized approach?
In general, SQL engines do a better job of optimizing queries than of optimizing function calls. I would suggest that you stick with the query, at least at first. This also makes it easier to understand performance issues that might arise.
By the way, there is no need for a subquery for what you want to do. SQL Server is pretty smart, so it probably doesn't affect performance. However, you can write the query as:
select at.Id , p.Name , e.Name , at.Start, at.End
from Patient p inner join
Attend at
on p.Id = at.PatientId inner join
Employee as e
on at.DoctorId = e.Id;
Some people like to embed such queries in stored procedures. If you want to encapsulate this logic, I would suggest a view or table-valued function instead.
I have three tables called Hours, Projects and Clients. I'm somewhat experienced with SQL statements and can't seem to get my head around why this isn't working.
Projects and Hours tables both share a foreign key called projectid
and Projects and Clients both share a foreign key called clientid.
Here's my query so far:
SELECT hoursworked.h, projectname.p, description.p, archive.p, clientname.c
FROM hours AS h, projects AS p, clients AS c
JOIN h
ON projectid.h = projectid.p
JOIN p
ON clientid.p = clientid.c
WHERE archive.p = 0;
I seem to be getting an error called "#1066 - Not unique table/alias: 'h' "
Not sure where I am going wrong here. Any help would be great.
Thanks in advance!
You are mixing implicit joins and explicit joins. A simple rule: don't use commas in from clauses.
SELECT h.hoursworked, p.projectname, p.description, p.archive, c.clientname
FROM hours h join
projects p
on h.projectid = p.projectid join
clients c
ON p.clientid = c.clientid
WHERE p.archive = 0;
In addition, the syntax for using aliases is <table alias>.<column alias>, not the other way around.
You are using your aliases backwards. You need to use H.HoursWorked, rather than HoursWorked.H, etc. Your JOIN is also incorrect.
Try the following:
SELECT h.hoursworked, p.projectname, p.description, p.archive, c.clientname
FROM hours AS h
JOIN projects AS p ON h.projectid = p.projectid
JOIN clients AS c ON p.clientid = c.clientid
WHERE p.archive = 0;
You need to prepend the table name to the field/column, not put it at the end, and usually you would use AS for field/column aliases, not for table aliases. Also, I would name the tables in the JOINs, not separated by commas in the FROM statement. This is how it should look:
SELECT
h.hoursworked,
p.projectname,
p.description,
p.archive,
c.clientname
FROM hours h
JOIN projects p
ON h.projectid = p.projectid
JOIN clients c
ON p.clientid = c.clientid
WHERE p.archive = 0;