Recently I've been working on some software which has a system in place that allows you to list specific data from an MSSQL table and display it in a web-based GUI. It has a few constrictions, though.
When comparing text, the only operators allowed are NOT NULL and LIKE.
Furthermore, every statement starts with SELECT * FROM MyTable WHERE.
The reason for that is the way the software we're using is programmed. Unfortunately, there isn't a way to change it and the developers don't seem to be planning on addressing the issue either.
This has been causing quite some trouble, but so far, there have always been ways to rewrite the statements.
Now, I've reached a point where I'm stuck. I've created a view that selects a specific subset of MyTable's rows. Now I want to display these
Tl;dr:
If I have this piece of code which I cannot modify, only append to:
SELECT * FROM MyTable WHERE
how do I perform an inner join with a different table from there, without using IN?
-
Thanks in advance!
Just for the laugh of it, I'd do something like that:
SELECT * FROM MyTable WHERE 0 = 1 UNION SELECT whatIWant FROM whereIWant
The 0 = 1 criteria discards all results from MyTable, only the right part of the union will return results. A problem is that you will still have to handle the columns from MyTable.
Use EXISTS
SELECT * FROM MyTable WHERE
exists (SELECT * from othertable as t2 where t2.col=MyTable.col)
I saw this query in one of the posts, to update a table by the records on another table, but I couldn't understand logic behind it. Especially I have never used FROM in an UPDATE query.
And...
(If I want to be blunt, I should say I am looking for an insight to understand how can I translate/debug/trace or in a nutshell understand SQL results by each line. When I see a line of code I know what is it doing, but so far, I could only memorize structure of SQL queries by practice.
I want to know which line would be processed first, what comes next and... so I can write more complex codes. Could you please provide me with a reference?)
UPDATE
T
SET
T.col1 = OT.col1,
T.col2 = OT.col2
FROM
Some_Table T
INNER JOIN
Other_Table OT
ON
T.id = OT.id
WHERE
T.col3 = 'cool'
Frist of all try this:
SELECT
T.col1 , OT.col1,
T.col2 , OT.col2
FROM
Some_Table T
INNER JOIN
Other_Table OT
ON
T.id = OT.id
WHERE
T.col3 = 'cool'
This will show you what is the result of the update would be.
First off, I found that in SQL Engines, hierarchies of processing commands are different, so there is no unique way of thinking and understanding SQL like lines of codes.
I also found out that FROM is usually process at first, and then it will goes up to select. In all SQL commands there are a unique hierarchy, so I simply think about SQL a human language and then try to find the logical way to do what I think it should have done, and in most cases this will work.
For example, in SELECT, the machine should first bring a table, and then find what condition should be apply, so WHERE is next, and then the data should be prepared for viewing, so SELECT will be processed next. This is the closest thing I found. :)
Here is the table (new user, can't post images yet):
I've always used Excel, but I'm switching over to SQL due to larger data sets. To populate CELL G2 in Excel, I would have used something like this:
=SUM((A2:A8=E2)*(B2:B8))
That gives a value of 141 in Excel for Cell G2.
I figured out how to get this to work in SQL, but I don't exactly understand why this works. Here's what I used in SQL:
SET Table2.total_units_purchased = Table1.some_number
FROM Table2 INNER JOIN
(
SELECT Table1.item
, SUM(Table1.units_purchased) AS some_number
FROM Table1
GROUP BY Table1.item
) Table1
ON Table2.item = Table1.item
Is the "AS" required before some_number? This still works for some reason even if I omit "AS".
Am I missing anything here? Does the order of the tables in the last line of code matter?
Thanks for any help.
Using 'AS' keyword in as an alias is optional, that's why your query still works when you omit the 'AS'.
Secondly, the order of the tables in the last line of code does not matter in this case. The query would work in the same way if your code was ON Table1.item = Table2.item. Note that table order matters if you are using left or right outer joins.
In your SQL code you are selecting the 'item' and the 'sum of the units purchased' for that item and you put these data into another table which you rename to Table1 again.
Then, you join two tables, Table2 and new Table1 where their item fields have the same value.
Lastly, you are selecting the 'sum of the units purchased' field and assign it to Table2's total_units_purchased field.
You could have written your SQL query as the following, which does the same thing with your Excel function.
select sum(table1.units_purchased)
into table2.total_units_purchased
from table1, table2
where Table2.item = Table1.item
I am trying to update records in an .mdb table with the number of records containing the same value.
The SQL below does not work but I think gives an indication of what I am trying to achieve.
UPDATE table1 AS A
INNER JOIN (SELECT PH_BSP , Count(PH_BSP) AS PHCOUNT FROM table1 GROUP BY PH_BSP) AS B
ON A.PH_BSP=B.PH_BSP
SET A.PH_SORT = B.PHCOUNT;
Any ideas?
If you are doing this in Access, you need to use a domain aggregate function:
UPDATE table1
SET PH_SORT = DCount("PH_BSP","Table1","PH_BSP='" & PH_BSP & "'")
The above assumes that PH_BSP is a text field, drop the single quotes if it is numeric.
Untested, but setting out the statement thusly this should solve your issue
UPDATE A
SET A.PH_SORT = B.PHCOUNT
From table1 AS A
INNER JOIN (SELECT PH_BSP , Count(PH_BSP) AS PHCOUNT FROM table1 GROUP BY PH_BSP) AS B
ON A.PH_BSP=B.PH_BSP
Edit:
Your problem might be from your sub query, I would try putting that part into a separate Access Query and see how it goes. From memory I used to have a lot of trouble with Access and subqueries, square brackets would also sometimes help, but unreliable from memory.
Have you tried something alike?
update table1 as a
set a.ph_sort = (
select COUNT(b.ph_bsp) as phcount
from table1 b
where b.ph_bsp = a.ph_bsp)
I'm assuming SQL Server here.
But this or something alike should do it, I guess.
I continually get these errors when I try to update tables based on another table. I end up rewriting the query, change the order of joins, change some groupings and then it eventually works, but I just don't quite get it.
What is a 'multi-part identifier'?
When is a 'multi-part identifier' not able to be bound?
What is it being bound to anyway?
In what cases will this error occur?
What are the best ways to prevent it?
The specific error from SQL Server 2005 is:
The multi-part identifier "..." could not be bound.
Here is an example:
SELECT * FROM [MainDB].[dbo].[Company]
WHERE [MainDB].[dbo].[Company].[CompanyName] = 'StackOverflow'
The actual error:
Msg 4104, Level 16, State 1, Line 2 The multi-part identifier
"MainDB.dbo.Company.CompanyName" could not be bound.
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. It can also be caused by using reserved words in your table or field names and not surrounding them with [].
It can also be caused by not including all of the required columns in the target table.
Something like redgate sql prompt is brilliant for avoiding having to manually type these (it even auto-completes joins based on foreign keys), but isn't free. SQL server 2008 supports intellisense out of the box, although it isn't quite as complete as the redgate version.
Actually sometimes when you are updating one table from another table's data, I think one of the common issues that cause this error, is when you use your table abbreviations incorrectly or when they are not needed. The correct statement is below:
Update Table1
Set SomeField = t2.SomeFieldValue
From Table1 t1
Inner Join Table2 as t2
On t1.ID = t2.ID
Notice that SomeField column from Table1 doesn't have the t1 qualifier as t1.SomeField but is just SomeField.
If one tries to update it by specifying t1.SomeField the statement will return the multi-part error that you have noticed.
It's probably a typo. Look for the places in your code where you call [schema].[TableName] (basically anywhere you reference a field) and make sure everything is spelled correctly.
Personally, I try to avoid this by using aliases for all my tables. It helps tremendously when you can shorten a long table name to an acronym of it's description (i.e. WorkOrderParts -> WOP), and also makes your query more readable.
Edit: As an added bonus, you'll save TONS of keystrokes when all you have to type is a three or four-letter alias vs. the schema, table, and field names all together.
Binding = your textual representation of a specific column gets mapped to a physical column in some table, in some database, on some server.
Multipart identifier could be: MyDatabase.dbo.MyTable. If you get any of these identifiers wrong, then you have a multipart identifier that cannot be mapped.
The best way to avoid it is to write the query right the first time, or use a plugin for management studio that provides intellisense and thus help you out by avoiding typos.
I found that I get these a lot when I try to abbreviate, such as:
Table1 t1, Table2 t2
where t1.ID = t2.ID
Changing it to:
Table1, Table2
where Table1.ID = Table2.ID
Makes the query work and not throw the error.
You probably have a typo. For instance, if you have a table named Customer in a database named Sales, you could refer to it as Sales..Customer (although it is better to refer to it including the owner name (dbo is the default owner) like Sales.dbo.Customer.
If you typed Sales...Customer, you might have gotten the message you got.
If you are sure that it is not a typo spelling-wise, perhaps it is a typo case-wise.
What collation are you using? Check it.
When updating tables make sure you do not reference the field your updating via the alias.
I just had the error with the following code
update [page]
set p.pagestatusid = 1
from [page] p
join seed s on s.seedid = p.seedid
where s.providercode = 'agd'
and p.pagestatusid = 0
I had to remove the alias reference in the set statement so it reads like this
update [page]
set pagestatusid = 1
from [page] p
join seed s on s.seedid = p.seedid
where s.providercode = 'agd'
and p.pagestatusid = 0
Adding table alias in front Set field causes this problem in my case.
Right
Update Table1
Set SomeField = t2.SomeFieldValue
From Table1 t1
Inner Join Table2 as t2
On t1.ID = t2.ID
Wrong
Update Table1
Set t1.SomeField = t2.SomeFieldValue
From Table1 t1
Inner Join Table2 as t2
On t1.ID = t2.ID
I had this issue and it turned out to be an incorrect table alias. Correcting this resolved the issue.
Mine was putting the schema on the table Alias by mistake:
SELECT * FROM schema.CustomerOrders co
WHERE schema.co.ID = 1 -- oops!
I had P.PayeeName AS 'Payer' --,
and the two comment lines threw this error
I actually forgot to join the table to the others that's why i got the error
Supposed to be this way:
CREATE VIEW reserved_passangers AS
SELECT dbo.Passenger.PassName, dbo.Passenger.Address1, dbo.Passenger.Phone
FROM dbo.Passenger, dbo.Reservation, dbo.Flight
WHERE (dbo.Passenger.PassNum = dbo.Reservation.PassNum) and
(dbo.Reservation.Flightdate = 'January 15 2004' and Flight.FlightNum =562)
And not this way:
CREATE VIEW reserved_passangers AS
SELECT dbo.Passenger.PassName, dbo.Passenger.Address1, dbo.Passenger.Phone
FROM dbo.Passenger, dbo.Reservation
WHERE (dbo.Passenger.PassNum = dbo.Reservation.PassNum) and
(dbo.Reservation.Flightdate = 'January 15 2004' and Flight.FlightNum = 562)
Error Code
FROM
dbo.Category C LEFT OUTER JOIN
dbo.SubCategory SC ON C.categoryID = SC.CategoryID AND C.IsActive = 'True' LEFT OUTER JOIN
dbo.Module M ON SC.subCategoryID = M.subCategoryID AND SC.IsActive = 'True' LEFT OUTER JOIN
dbo.SubModule SM ON M.ModuleID = SM.ModuleID AND M.IsActive = 'True' AND SM.IsActive = 'True' LEFT OUTER JOIN
dbo.trainer ON dbo.trainer.TopicID =dbo.SubModule.subModuleID
Solution Code
FROM
dbo.Category C LEFT OUTER JOIN
dbo.SubCategory SC ON C.categoryID = SC.CategoryID AND C.IsActive = 'True' LEFT OUTER JOIN
dbo.Module M ON SC.subCategoryID = M.subCategoryID AND SC.IsActive = 'True' LEFT OUTER JOIN
dbo.SubModule SM ON M.ModuleID = SM.ModuleID AND M.IsActive = 'True' AND SM.IsActive = 'True' LEFT OUTER JOIN
dbo.trainer ON dbo.trainer.TopicID = SM.subModuleID
as you can see, in error code, dbo.SubModule is already defined as SM, but I am using dbo.SubModule in next line, hence there was an error.
use declared name instead of actual name. Problem solved.
My best advise when having the error is to use [] braquets to sorround table names, the abbreviation of tables causes sometimes errors, (sometime table abbreviations just work fine...weird)
I was getting this error and just could not see where the problem was. I double checked all of my aliases and syntax and nothing looked out of place. The query was similar to ones I write all the time.
I decided to just re-write the query (I originally had copied it from a report .rdl file) below, over again, and it ran fine. Looking at the queries now, they look the same to me, but my re-written one works.
Just wanted to say that it might be worth a shot if nothing else works.
When you type the FROM table those errors will disappear.
Type FROM below what your typing then Intellisense will work and multi-part identifier will work.
I faced this problem and solved it but there is a difference between your and mine code. In spite of I think you can understand what is "the multi-part identifier could not be bound"
When I used this code
select * from tbTest where email = sakira#gmail.com
I faced Multi-part identifier problem
but when I use single quotation for email address It solved
select * from tbTest where email = 'sakira#gmail.com'
I had exactly the same issue, and similar to your coding I had missed out the FROM field, once it is added, the query knows what table to read the data from
Mine worked after removing square brackets in a SUBSTRING method. I changed from
SUBSTRING([dbo.table].[column],15,2)
to
SUBSTRING(dbo.table.column,15,2)
CTRL+SHIFT+R (refreshing the Intellisense) took care of it for me.