Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The multi-part identifier could not be bound in left outer join with table values function

I write this code

SELECT tblprsn.prsnid, tblprsn.name 
FROM tblprsn LEFT OUTER JOIN 
             (
                SELECT tblrtm.rtmid 
                FROM dbo.getrtmn(tblprsn.prsnid) as getrtmn_1
             ) AS tblgetrtmn 
             ON tblprsn.prsnid = tblgetrtmn.rtmid

the dbo.getrtmn is a table-value function and have a uniqueidentifier field named rtmid. prsnid is uniqueidentifier

When I run this SQL query cause error:

The multi-part identifier " tblprsn.prsnid" could not be bound.

like image 505
Phoenix Avatar asked Jun 01 '13 06:06

Phoenix


People also ask

What is multipart identifier in SQL?

A multipart identifier is any description of a field or table that contains multiple parts - for instance MyTable. SomeRow - if it can't be bound that means there's something wrong with it - either you've got a simple typo, or a confusion between table and column.

What is left outer join with example?

A left outer join is a method of combining tables. The result includes unmatched rows from only the table that is specified before the LEFT OUTER JOIN clause. If you are joining two tables and want the result set to include unmatched rows from only one table, use a LEFT OUTER JOIN clause or a RIGHT OUTER JOIN clause.

Could not be bound meaning?

could not be bound. The main reason for this error is that the source table cannot be found, for example if you have statement such as Table1. OrderDate, and then if you get error above, this means that Table1 cannot be found in the query.

Is Outer Join Left or right?

Left outer join includes the unmatched rows from the table which is on the left of the join clause whereas a Right outer join includes the unmatched rows from the table which is on the right of the join clause.


2 Answers

This is your query:

SELECT tblprsn.prsnid, tblprsn.name 
FROM tblprsn LEFT OUTER JOIN 
     (SELECT tblrtm.rtmid 
      FROM dbo.getrtmn(tblprsn.prsnid) as getrtmn_1
     ) AS tblgetrtmn 
     ON tblprsn.prsnid = tblgetrtmn.rtmid

You are referencing the first table in the subquery. This isn't allowed. First, I don't think the subquery is necessary. You are only selecting from the first table and doing a left outer join to keep all the records. The only affect of the subquery would be to multiply the rows. So, as you have written it, this query should do pretty much the same thing (except for duplicates):

SELECT tblprsn.prsnid, tblprsn.name 
FROM tblprsn;

You can do what you want in the original query, though, using apply rather than join:

SELECT tblprsn.prsnid, tblprsn.name 
FROM tblprsn cross apply 
     dbo.getrtmn(tblprsn.prsnid) tblgetrtmn 
where tblprsn.prsnid = tblgetrtmn.rtmid
like image 54
Gordon Linoff Avatar answered Sep 28 '22 16:09

Gordon Linoff


instead of LEFT OUTER JOIN use OUTER APPLY with correleted subquery. The OUTER APPLY clause return all the rows on the left side table whether they return any rows in the table -valued-function or not, and thus similar to LEFT OUTER JOIN

SELECT t.prsnid, t.name, getrtmn_1.*
FROM tblprsn t OUTER APPLY (
                            SELECT rtmid 
                            FROM dbo.getrtmn(t.prsnid) AS tblgetrtmn
                            WHERE t.prsnid = tblgetrtmn.rtmid  
                            ) as getrtmn_1

Demo on SQLFiddle

like image 44
Aleksandr Fedorenko Avatar answered Sep 28 '22 14:09

Aleksandr Fedorenko