I know this might shock some but I just cant figure out what's wrong with this SQL statement.. it kills my head.
SELECT * FROM groups WHERE gname LIKE '%m%';
I am using mysql 5.1.41
If you don't get any rows back, perhaps that's the right answer. Mistakes usually happen when your assumptions don't match the situation at hand.
Are you sure you have values in the gname column with lower case 'm' in them?
Are you sure you're running the query against the database you think you are?
This statement will retrieve every column and every row from the groups table where the gname column contains a lowercase m somewhere. Is this what you wanted to achieve?
Related
My Access 2010 database has a linked table (on a SQL Server 2012 backend), containing fields ID, Qty, PackSize. My query is meant to select records where Qty is not a multiple of the packsize. Normally I achieve this with a where clause like so: "Where Qty/Packsize <> Fix(Qty/Packsize), but although this works on local tables or linked tables that live in other Access databases, on linked tables which live in SQL server, it returns no results.
If I split up the query into two parts, one with no where clause, creating a new table with ColA: Qty/Packsize, ColB: Fix(Qty/PackSize), and then select where ColA <> ColB, it works fine.
Since I don't really care what the values are, just to know whether they're different, I also tried Int() instead of Fix.
Even weirder, "Where Cdbl(Qty/Packsize) = int(Qty/Packsize)" returns all the records, despite showing me that Cdbl(Qty/Packsize) is for example 425.5 and int(Qty/Packsize) is 425.
Any idea what's going on or how I can achieve this another way? It needs to be in a single step though, as it's really the basis for a record selection in VBA. Why would it not work over a SQL linked table? I've tried in separate databases as well and using a different SQL table, in case it was merely a glitch.
Many thanks in advance.
(Also the title of this question is awful. Edits gratefully received.)
It could be a floating point issue, so try with integers only:
Where Qty <> Fix(Qty/Packsize) * Packsize
By the way, Fix and Int behave the same for positive values.
Warning: This is a soft question, where you'll be answering to someone who has just started teaching himself SQL from the ground up. I haven't gotten my database software set up yet, so I can't provide tables to run queries against. Some patience required.
Warnings aside, I'm experimenting with basic SQL but I'm having a little bit of a rough time getting a clear answer about the inner workings of subqueries and their execution order within my query.
Let us say my query looks something like shit:
SELECT * FROM someTable
WHERE someFirstValue = someSecondValue
AND EXISTS (
SELECT * FROM someOtherTable
WHERE someTable.someFirstValue = someOtherTable.someThirdValue
)
;
The reason I'm here, is because I don't think I understand fully what is going on in this query.
Now I don't want to seem lazy, so I'm not going to ask you guys to "tell me what's going on here", so instead, I'll provide my own theory first:
The first row in someTable is checked so see if someFirstValue is the same as someSecondValue in that row.
If it isn't, it goes onto the second row and checks it too. It continues like this until a row passes this little inspection.
If a row does pass, it opens up a new query. If the table produced by this query contains even a single row, it returns TRUE, but if it's empty it returns FALSE.
My theory ends here, and my confusion begins.
Will this inner query now compare only the rows that passed the first WHERE? Or will it check all the items someTable and someOtherTable?
Rephrased; will only the rows that passed the first WHERE be compared in the someTable.someFirstValue = someOtherTable.someThirdValue subquery?
Or will the subquery compare all the elements from someTable to all the elements in someOtherTable regardless of which passed the first WHERE and which didn't?
UPDATE: Assume I'm using MySQL 5.5.32. If that matters.
The answer is that SQL is a descriptive language that describes the result set being produced from a query. It does not specify how the query is going to be run.
In your case the query has several options on how it might run, depending on the database engine, what the tables look like, and indexes. The query itself:
SELECT t.*
FROM someTable t
WHERE t.someFirstValue = t.someSecondValue AND
EXISTS (SELECT *
FROM someOtherTable t2
WHERE t.someFirstValue = t2.someThirdValue
);
Says: "Get me all columns from SomeTable where someFirstValue = someSecondValue and there is a corresponding row in someOtherTable where that's table column someThirdValue is the same as someFirstValue".
One possible way to approach this query would be to scan someTable and first check for the first condition. When the two columns match, then look up someFirstValue in an index on someOtherTable(someThirdValue) and keep the row if the values match. As I say, this is one approach, and there are others.
in my database i have 10 records with almost exact same data , they differ only by one field ( the field is not in the query) and when i run the following query
SELECT * FROM friends WHERE user_id= 'MyUserName' AND follow_back = 0 AND until_date= '2009-10-13' LIMIT 12
it shows only 9 records , any one stumbled upon similar problem ?
Thanks & waiting for your answers !
The short answer is there's nothing wrong with your query, so
user_id!='MyUserName'
or
follow_back != 0
or
until_date != '2009-10-13'
Try just querying on one criterion at a time and see if you can norrow it down. Perhaps follow_back is NULL?
When trying to debug problems like these, what I would usually do is to try solving it using a divide and conquer approach.
So try and remove one where condition at a time, then execute the query. That way you will be able to isolate the offending condition.
Good luck
Are you sure, that all values in column user_id are the same? Maybe that one missing record has user_id = 'MyUserName ' (note the space).
I had the same problem a minute ago. It turned out it wasn't the query that was the problem, but the IF where I check if anything's returned. Might want to check that.
Is there a way that I can do a select as such
select * from attributes where product_id = 500
would return
id name description
1 wheel round and black
2 horn makes loud noise
3 window solid object you can see through
and the query
select * from attributes where product_id = 234
would return the same results as would any query to this table.
Now obviously I could just remove the where clause and go about my day. But this involves editing code that I don't really want to modify so i'm trying to fix this at the database level.
So is there a "magical" way to ignore what is in the where clause and return whatever I want using a view or something ?
Even if it was possible, I doubt it would work. Both of those WHERE clauses expect one thing to be returned, therefore the code would probably just use the first row returned, not all of them.
It would also give the database a behaviour that would make future developers pull their hair out trying to understand.
Do it properly and fix the code.
or you could pass "product_id" instead of an integer, if there's no code checking for that...so the query would become:
select * from attributes where product_id = product_id;
this would give you every row in the table.
If you can't edit the query, maybe you can append to it? You could stick
OR 1=1
on the end.
You may be able to use result set metadata to get what you want, but a result set won't have descriptions of fields. The specific API to get result set metadata from a prepared query varies by programming language, and you haven't said what language you're using.
You can query the INFORMATION_SCHEMA for the products table.
SELECT ordinal_position, column_name, column_comment
FROM INFORMATION_SCHEMA.columns
WHERE table_name = 'products' AND schema_name = 'mydatabase';
You can restructure the database into an Entity-Attribute-Value design, but that's a much more ambitious change than fixing your code.
Or you can abandon SQL databases altogether, and use a semantic data store like RDF, which allows you to query metadata of an entity in the same way you query data.
As far out as this idea seems I'm always interested in crazy ways to do things.
I think the best solution I could come up with is to use a view that uses the products table to get all the products then the attributes table to get the attributes, so every possible product is accounted for and all will get the same result
It's common to have a table where for example the the fields are account, value, and time. What's the best design pattern for retrieving the last value for each account? Unfortunately the last keyword in a grouping gives you the last physical record in the database, not the last record by any sorting. Which means IMHO it should never be used. The two clumsy approaches I use are either a subquery approach or a secondary query to determine the last record, and then joining to the table to find the value. Isn't there a more elegant approach?
could you not do:
select account,last(value),max(time)
from table
group by account
I tested this (granted for a very small, almost trivial record set) and it produced proper results.
Edit:
that also doesn't work after some more testing. I did a fair bit of access programming in a past life and feel like there is a way to do what your asking in 1 query, but im drawing a blank at the moment. sorry.
After literally years of searching I finally found the answer at the link below #3. The sub-queries above will work, but are very slow -- debilitatingly slow for my purposes.
The more popular answer is a tri-level query: 1st level finds the max, 2nd level gets the field values based on the 1st query. The result is then joined in as a table to the main query. Fast but complicated and time-consuming to code/maintain.
This link works, still runs pretty fast and is a lot less work to code/maintain. Thanks to the authors of this site.
http://access.mvps.org/access/queries/qry0020.htm
The subquery option sounds best to me, something like the following psuedo-sql. It may be possible/necessary to optimize it via a join, that will depend on the capabilities of the SQL engine.
select *
from table
where account+time in (select account+max(time)
from table
group by account
order by time)
This is a good trick for returning the last record in a table:
SELECT TOP 1 * FROM TableName ORDER BY Time DESC
Check out this site for more info.
#Tom
It might be easier for me in general to do the "In" query that you've suggested. Generally I do something like
select T1.account, T1.value
from table T as T1
where T1 = (select max(T2.time) from table T as T2 where T1.account = T2.Account)
#shs
yes, that select last(value) SHOULD work, but it doesn't... My understanding although I can't produce an authorative source is that the last(value) gives the last physical record in the access file, which means it could be the first one timewise but the last one physically. So I don't think you should use last(value) for anything other than a really bad random row.
I'm trying to find the latest date in a group using the Access 2003 query builder, and ran into the same problem trying to use LAST for a date field. But it looks like using MAX finds the lates date.
Perhaps the following SQL is clumsy, but it seems to work correctly in Access.
SELECT
a.account,
a.time,
a.value
FROM
tablename AS a INNER JOIN [
SELECT
account,
Max(time) AS MaxOftime
FROM
tablename
GROUP BY
account
]. AS b
ON
(a.time = b.MaxOftime)
AND (a.account = b.account)
;