I am using SQL Server 2008 R2. I want to join tables but always get the error
The multi-part identifier could not be bound
I have 3 tables Drivers, Request and Journey. I have driver_id foreign key in Journey. How can I join these tables to get details of all three tables??
Select driver.driver_name
from Drivers,
Journey
where driver.id = journey.id
and driver.id=1;
This error usually occurs when an alias is used when referencing a column in a SELECT statement and the alias used is not defined anywhere in the FROM clause of the SELECT statement.
For more details visit here
You only seem to be joining two of your three tables - correct?
The proper, ANSI SQL-92 standard-compliant way to do this would be:
SELECT
driver.driver_name
FROM
Drivers
INNER JOIN
Journey ON driver.id = journey.id
WHERE
driver.id = 1;
This is using the ANSI standard (in place since 1992 - more than 20 years now!) JOIN syntax of INNER JOIN (there's also LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL JOIN and a few more) instead of just comma-separating a list of tables in the FROM clause.
See Aaron Bertrand's excellent blog post Bad habits to kick : using old-style JOINs on that topic, too.
driver+s
Select Drivers.driver_name
from Drivers,
Journey
where Drivers.id = journey.id
and Drivers.id=1;
Related
I'm trying to do this in a SQL Server CE database, but the database engine keeps reporting errors.
SELECT C.guid, C.name, C.updated,
C.hddsize, C.hddavailable, C.hddfree,
C.ramsize, C.profiles, C.cpu,
(SELECT COUNT(D.id) AS numprogs
FROM ComputerData AS D
WHERE D.computer_id = C.id) AS numprograms
FROM Computers AS C;
I've been told SQL Server CE supports subqueries. Is there something I'm doing wrong?
The limitation in SQL CE is that it does not support subqueries that return a scalar value. Subqueries that return a set are parsed fine.
The subquery in the join in Grayson's answer returns a set, so it should work. Sometimes a scalar subquery cannot be avoided in a join condition. By using 'IN' instead of '=', the parser can be tricked.
See my answer to this question.
My only experiences in queries are with MySQL, but hopefully it is similar enough.
Your query looks strange to me because your subquery is in the SELECT clause. I have never seen that before... but apparently it is supported in MySQL. Usually the subquery comes in the after a FROM or LEFT JOIN or JOIN.
Your example is simple enough that you could implement it with a LEFT JOIN:
SELECT C.guid, ..., COUNT(distinct D.id) as numprogs
FROM Computers AS C
LEFT JOIN ComputerData as D ON D.computer_id = C.id
In this case, LEFT JOIN is the correct type of join to use because even if there is no matching record in the D table for a particular C record, your result set will still contain that C record and numprogs will just be zero, as you would expect.
If you really want to use a subquery, try this:
SELECT C.guid, ..., S.numprogs
FROM Computers AS C
LEFT JOIN
(SELECT computer_id, COUNT(*) as numprogs
FROM ComputerData GROUP BY computer_id) AS S
ON C.id=S.computer_id
I suggest simplifying your query to get it to be the simplest possible query that should work, but doesn't work. Then tell us the specific error message that your database engine is returning.
Edit: I loooked in the MySQL chapter about subqueries and it seems like you should try removing the "as numprograms" clause after your subquery... maybe you don't get any choice about the naming of the column that comes out of the subquery after you've already composed the subquery.
I am looking to sort the details of number of DB's present in the SQL instance along with their Recovery model type and the size.?
ex: name , recovery_model_desc resides under sys.databases and size from sys.master_files. Also database_id is the shared column.
How to get the result in together?
JOIN the two tables together on the key field you have correctly identified:
SELECT db.*, mf.*
FROM sys.databases db
LEFT JOIN sys.master_files mf ON db.database_id = mf.database_id
I suspect that the LEFT JOIN could just be JOIN/INNER JOIN as I don't think there can be records in sys.databases without any corresponding records in sys.master_files, but I don't know for sure, so stuck with a LEFT JOIN for that reason.
If you need some basics around JOINs to get you started with understanding how this works, here are some resources:
MSDN Blog: Introduction to Joins
W3 Schools: SQL Joins
SQL Authority: Introduction to JOINs
Essential SQL: Introduction to Database Joins
I've also often found a visual explanation of SQL Joins to be a helpful reference at times.
I'm rewriting a bunch of old, badly written Oracle queries against a new(-er) Sql Server 2008 environment. They use old-school Oracle join syntax like
select <whatever>
from Table1, Table2, Table3
where Table1.T1ID = Table2.T2ID -- old Oracle inner join
and Table2.T3ID = Table3.T3ID (+) -- old Oracle left join (I think)
Except a lot more complicated. There's a lot of mixed joins and a lot of nesting and a lot of views piled on views going on in these things. It's not pretty. The data is disparate between the two servers too, making testing a chore.
I figured the easiest way to replicate would be to make the queries look as similar as possible in Sql Server (ie, using the same style of join), and then do a massive clean-up job after once I'm confident they're both definitely doing the same thing & I don't have a join in the wrong place somewhere (and yes, I have compatibility mode temporarily set to support old joins).
I know the 'old' syntax for an inner join in T-Sql is
select <whatever>
from T1, T2
where T1.ID = T2.ID
but what is the 'old' syntax for a left outer join or a right outer join?
From the documentation on TechNet (on SQL Server 2000, so be aware this might not be supported any more!), you need to use *= instead of the (+) as Oracle does:
select <whatever>
from T1, T2
where T1.ID *= T2.ID
THe below 2 queries performs the same operation, but wondering which would be the fastest and most preferable?
NUM is the primary key on table1 & table2...
select *
from table1 tb1,
table2 tb2
where tb1.num = tb2.num
select *
from table1 tb1
inner join
table2 tb2
on tb1.num = tb2.num
They are the same query. The first is an older alternate syntax, but they both mean do an inner join.
You should avoid using the older syntax. It's not just readability, but as you build more complex queries, there are things that you simply can't do with the old syntax. Additionally, the old syntax is going through a slow process of being phased out, with the equivalent outer join syntax marked as deprecated in most products, and iirc dropped already in at least one.
The 2 SQL statements are equivalent. You can look at the execution plan to confirm. As a rule, given 2 SQL statements which affect/return the same rows in the same way, the server is free to execute them the same way.
They're equivalent queries - both are inner joins, but the first uses an older, implicit join syntax. Your database should execute them in exactly the same way.
If you're unsure, you could always use the SQL Management Studio to view and compare the execution plans of both queries.
The first example is what I have seen referred to as an Oracle Join. As mentioned already there appears to be little performance difference. I prefer the second example from a readability standpoint because it separates join conditions from filter conditions.
I have a sql server query that returns rows more than I expected:
select
b.isbn, l.lend_no, s.first_name
from
dbo.books b, dbo.lending l, dbo.students s
where
(l.act between '4/16/2013' and '4/16/2013')
and (l.stat ='close')`
I want to do is get the isbn, lend_no and student name that book returned date is between given dates and lend status is closed , my lending table has only 2 lending that returned on given date but query give me 304 rows
Your current query gets the cartesian product from the three tables causing to retrieve unexpected result. You need to define the relationship or how the tables should be join, example
select b.isbn, l.lend_no, s.first_name
from dbo.books b
INNER JOIN dbo.lending l
ON c.Colname = l.ColName -- << define condition here
INNER JOIN dbo.students s
ON ...... -- << define condition here
where l.act between '4/16/2013' and '4/16/2013' and
l.stat ='close'
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
You're not definining any join conditions between the tables, so you'll get a cartesian product.
Try something like this instead:
SELECT
b.isbn, l.lend_no, s.first_name
FROM
dbo.books b
INNER JOIN
dbo.lending l ON l.Book_id = b.Book_id -- just guessing here
INNER JOIN
dbo.students s ON l.student_id = s.student_id -- just guessing here
WHERE
l.act BETWEEN '20130416' AND '20130416'
AND l.stat = 'close'
Define the join conditions as needed - I don't know your tables, you'll have to find out what columns link the two tables respectively.
I also used the proper ANSI JOIN syntax - don't just list a bunch of tables separated by a comma, that's been kicked out of the SQL standards over 20 years ago (SQL 1992).
Also: I would always use the ISO-8601 date format YYYYMMDD to be safe - this is the only format that works on all versions of SQL Server and with all language, regional and dateformat settings.
Your FROM clause isn't doing what you expect it to. By specifying the tables that way you are doing a full join which is giving you a cartesian product. You need to be using the proper table join syntax.
This is a great explanation of table joins: http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html