I found a very strange looking query in one of the MS-Access databases today:
SELECT Count([hrpersnl Without Matching T_Employees].EmpNo) AS [Count]
FROM [hrpersnl Without Matching T_Employees];
The Without Matching clause seems to me to be rather MS-Access specific syntax that differs from ANSI-SQL as a whole, it appears to me to be finding records that have no matches on the EmpNo field of both tables, but the T_Employees table does not have a EmpNo field, so I am probably wrong in my assumption about this.
What does it actually do, and where is the documentation for it?
In an Access query, table/query and field names that
contain spaces and "funny characters", or
are Access reserved words
must be enclosed in [square brackets]. In this case, [hrpersnl Without Matching T_Employees] was a table or query name, not an expression involving the base tables hrpersnl and T-Employees.
Related
I can get the 'Name' Column in one query but when combined with that of another I get an "Invalid column name" output.
select Name
from Tb_Product;
Here I get the expected output of the product 'Name' and all is well...
select City, Name
FROM Tb_Supplier Stbl, Tb_Product Ptbl
WHERE Stbl.City = 'Chicago'
But, here the 'Name' column is invalid...
try fully specifying the name:
select City, Ptbl.Name
FROM Tb_Supplier Stbl, Tb_Product Ptbl
WHERE Stbl.City = 'Chicago'
also, you do not have a join condition between the supplier and the product... this query will likely not give you the results you are expecting.
Another possible issue is that name is a reserved keyword:
https://dev.mysql.com/doc/refman/8.0/en/keywords.html#keywords-8-0-detailed-N
DBMSes or programming languages have reserved keywords that should be avoided for naming objects. They may still work but yield unexpected results, or produce confusing error messages that are not so easy to debug.
It's possible to get around this by qualifying the column name with a table prefix as suggested by Randy, or enclosing the column name between brackets ([]). But it's best to avoid overly generic object names, as there is a chance that you will sometimes stumble upon reserved keywords. If in doubt - check the list. Read it in full and bookmark it :)
The tags for the question are not consistent though, because they mention both SQL Server and MySQL, unless you really work with both. The lists of reserved keywords vary from one platform to another.
i have a table called ORDER, when i try to query it using
select * from Order
i get the error 'invalid query'
how to do access this table please?
thank you
Step 1
Don't ever used reserved words for object (or column) names.
SQL 1992 Standard (search for <reserved word>)
SQL Server reserved words
MySQL reserved words
DB2 reserved words
Step 2
If you've inherited such a thing that you are not able to change, then you need to use "quoted identifiers".
I advocate
SELECT *
FROM "Order"
As it is a standard identifier, so will work better across platforms.
ORDER is a reserved word in SQL. Put double quotes around it:
select * from "Order"
And also, I personally think ORDERS is a better name. (Because several orders are stored in the table.)
Late edit: List of reserved words, in different versions of the SQL standard:
http://developer.mimer.com/standard/reservedwords/sql-reserved-words.tml
It's generally a good idea to not use reserved words for database object names (tables, views & etc.). Sometimes you just got to deal with it though. The below query should work for you.
select * from [Order]
Just put the brackets around the table name.
Hope this helps!
When i write a select statement in vba to grab a column from a query its empty.
i have a query thats joined by multiple tables.
For example if I call select query.specialcolumn from query where query.id=5 I get a blank back. However, If I view it in the query table I see data for ID=5 with data.
Straight SQL in design mode also produces blanks. Only when I view the query as a whole, I can see data.
Any ideas?
Sounds like you used "query" as the name for your saved query. And query is a reserved word, see Problem names and reserved words in Access. It's hard predict when reserved words as object names will create problems. And I'm not confident that name is the problem here. But I would rule it out first before investigating anything else.
Enclose query in square brackets everywhere it's referenced in the SQL.
select [query].specialcolumn from [query] where [query].id=5
The square brackets will inform the db engine that query is a database object rather than the reserved word.
I suppose I have always naively assumed that scalar functions in the select part of a SQL query will only get applied to the rows that meet all the criteria of the where clause.
Today I was debugging some code from a vendor and had that assumption challenged. The only reason I can think of for this code failing is that the Substring() function is getting called on data that should have been filtered out by the WHERE clause. But it appears that the substring call is being applied before the filtering happens, the query is failing.
Here is an example of what I mean. Let's say we have two tables, each with 2 columns and having 2 rows and 1 row respectively. The first column in each is just an id. NAME is just a string, and NAME_LENGTH tells us how many characters in the name with the same ID. Note that only names with more than one character have a corresponding row in the LONG_NAMES table.
NAMES: ID, NAME
1, "Peter"
2, "X"
LONG_NAMES: ID, NAME_LENGTH
1, 5
If I want a query to print each name with the last 3 letters cut off, I might first try something like this (assuming SQL Server syntax for now):
SELECT substring(NAME,1,len(NAME)-3)
FROM NAMES;
I would soon find out that this would give me an error, because when it reaches "X" it will try using a negative number for in the substring call, and it will fail.
The way my vendor decided to solve this was by filtering out rows where the strings were too short for the len - 3 query to work. He did it by joining to another table:
SELECT substring(NAMES.NAME,1,len(NAMES.NAME)-3)
FROM NAMES
INNER JOIN LONG_NAMES
ON NAMES.ID = LONG_NAMES.ID;
At first glance, this query looks like it might work. The join condition will eliminate any rows that have NAME fields short enough for the substring call to fail.
However, from what I can observe, SQL Server will sometimes try to calculate the the substring expression for everything in the table, and then apply the join to filter out rows. Is this supposed to happen this way? Is there a documented order of operations where I can find out when certain things will happen? Is it specific to a particular Database engine or part of the SQL standard? If I decided to include some predicate on my NAMES table to filter out short names, (like len(NAME) > 3), could SQL Server also choose to apply that after trying to apply the substring? If so then it seems the only safe way to do a substring would be to wrap it in a "case when" construct in the select?
Martin gave this link that pretty much explains what is going on - the query optimizer has free rein to reorder things however it likes. I am including this as an answer so I can accept something. Martin, if you create an answer with your link in it i will gladly accept that instead of this one.
I do want to leave my question here because I think it is a tricky one to search for, and my particular phrasing of the issue may be easier for someone else to find in the future.
TSQL divide by zero encountered despite no columns containing 0
EDIT: As more responses have come in, I am again confused. It does not seem clear yet when exactly the optimizer is allowed to evaluate things in the select clause. I guess I'll have to go find the SQL standard myself and see if i can make sense of it.
Joe Celko, who helped write early SQL standards, has posted something similar to this several times in various USENET newsfroups. (I'm skipping over the clauses that don't apply to your SELECT statement.) He usually said something like "This is how statements are supposed to act like they work". In other words, SQL implementations should behave exactly as if they did these steps, without actually being required to do each of these steps.
Build a working table from all of
the table constructors in the FROM
clause.
Remove from the working table those
rows that do not satisfy the WHERE
clause.
Construct the expressions in the
SELECT clause against the working table.
So, following this, no SQL dbms should act like it evaluates functions in the SELECT clause before it acts like it applies the WHERE clause.
In a recent posting, Joe expands the steps to include CTEs.
CJ Date and Hugh Darwen say essentially the same thing in chapter 11 ("Table Expressions") of their book A Guide to the SQL Standard. They also note that this chapter corresponds to the "Query Specification" section (sections?) in the SQL standards.
You are thinking about something called query execution plan. It's based on query optimization rules, indexes, temporaty buffers and execution time statistics. If you are using SQL Managment Studio you have toolbox over your query editor where you can look at estimated execution plan, it shows how your query will change to gain some speed. So if just used your Name table and it is in buffer, engine might first try to subquery your data, and then join it with other table.
Suppose that two tables exist: users and groups.
How does one provide "simple search" in which a user enters text and results contain both users and groups whose names contain the text?
The result of the search must distinguish between the two types.
The trick is to combine a UNION with a literal string to determine the type of 'object' returned. In most (?) cases, UNION ALL will be more efficient, and should be used unless duplicates are required in the sub-queries. The following pattern should suffice:
SELECT "group" type, name
FROM groups
WHERE name LIKE "%$text%"
UNION ALL
SELECT "user" type, name
FROM users
WHERE name LIKE "%$text%"
NOTE: I've added the answer myself, because I came across this problem yesterday, couldn't find a good solution, and used this method. If someone has a better approach, please feel free to add it.
If you use "UNION ALL" then the db doesn't try to remove duplicates - you won't have duplicates between the two queries anyway (since the first column is different), so UNION ALL will be faster.
(I assume that you don't have duplicates inside each query that you want to remove)
Using LIKE will cause a number of problems as it will require a table scan every single time when the LIKE comparator starts with a %. This forces SQL to check every single row and work it's way, byte by byte, through the string you are using for comparison. While this may be fine when you start, it quickly causes scaling issues.
A better way to handle this is using Full Text Search. While this would be a more complex option, it will provide you with better results for very large databases. Then you can use a functioning version of the example Bobby Jack gave you to UNION ALL your two result sets together and display the results.
I would suggest another addition
SELECT "group" type, name
FROM groups
WHERE UPPER(name) LIKE UPPER("%$text%")
UNION ALL
SELECT "user" type, name
FROM users
WHERE UPPER(name) LIKE UPPER("%$text%")
You could convert $text to upper case first or do just do it in the query. This way you get a case insensitive search.