I need to write a query that combines a variable number of AND WHERE statements.
One statement would look like
SELECT name
FROM users
WHERE field_id=16
AND value BETWEEN 1 AND 100
but I need to return one array of results from a variable amount of fields so field_id's of 16,18,20,25 with each field_id having a specific "AND value..." criteria.
How could I go about doing this to return on set of values?
I am also getting the criteria for the search from a html form and processing it using php (wordpress)
If field_id needs to relate to the value field criteria, you need to AND your field_id and value values together while ORing each set of criteria.
SELECT name
FROM users
WHERE (field_id=16 AND value BETWEEN 1 AND 100)
OR (field_id=17 AND value between 101 and 199)
OR (field_id=18 AND value between 201 and 299)
OR (...
You may also be looking for an IN statement. Which would look like this.
SELECT name
FROM users
WHERE (field_id IN (16,17,18) AND value IN (100,200,300))
...
Fiddle
You can use combination of AND and OR conditions:
SELECT name
FROM users
WHERE (field_id=16 AND value BETWEEN 1 AND 100)
OR (field_id=18 AND value BETWEEN 1 AND 150)
OR (field_id=20 AND value BETWEEN 10 AND 50)
OR (field_id=25 AND value BETWEEN 100 AND 500)
....
Related
Initial attempts at getting a very simple pagination, using fetch n rows and then a subsequent call with offset, gives overlapping entries in Oracle.
I was expecting the following to give me two unique sets of results. 1-100 and then 101-200 of the results that would have been returned if the first line had been set with a limit of 200.
select * from "APPR" /*+ index(APPR APPR_IDX01) */ where ("APPROVER" = 'A') or ("APPROVER" > 'A') order by "APPROVER" fetch first 100 rows only ;
select * from "APPR" /*+ index(APPR APPR_IDX01) */ where ("APPROVER" = 'A') or ("APPROVER" > 'A') order by "APPROVER" offset 100 rows fetch next 100 rows only ;
So if there are 150 items for approver A the first results should be:
A, item1
....
A, item100
The subsequent call (offset by 100) giving
A, item101
...
A, item150
B, item1
B, item2
....
B, item201
Unfortunately the second set contains some entries from the first batch of values. Probably a really silly error, but I can't find an explanation as to why this should happen.
---- Updated as a result of comments
The Primary key consists of Approver and several other fields which together form a composite and unique primary.
The code will be called through ODBC and will be used on Oracle and MySQL back-end.
In Oracle, if you make "order by" to a column containing same values (like you have - 'A', 'A', 'A' ...) the order of records inside 'A' values will be random.
Please try to change your queries to ... order by "APPROVER", rowid ...
Presumably, APPROVER is not a unique column. Since there may be duplicates, the order by claus is not stable, and the offset clause might generate duplicates.
A simple solution is to add more columns to the order by to break the ties. Assuming that (approver, item) is a unique set of columns, that would be:
select *
from appr
where approver = 'A' or approver > 'A'
order by approver, item
fetch first 100 rows only
-- then: offset 100 rows fetch next 100 rows only
Notes:
there is no need to surround all-caps identifiers (tables or column names) with double quotes: that's the default in Oracle already
parentheses around the or conditions are superfluous in this simple case
if approver is always one character long, then the where clause can be simplified as where approver >= 'A'
use index hints only if you really know why you are doing it (I am not saying you don't, but I removed it, just in case); most of the time, the database knows better
My table has only got 1 Column 'Name' with 100 unique entries.
I need to find out if a given Value exists in that table.
I am using:
SELECT 1 FROM `tbl_names` WHERE `Name` = "Lisa"
MySQL returns an empty result, so no 0 for not found and no 1 for found, even though the given name is an entry in that table.
What am I missing here?
select count(*) from tbl_name where name = 'Lisa' - will return count of entries with Lisa in the column. You can do as before with select 1, and calculate results - zero size means no occurance
If you want to return as 0 or 1, I would suggest:
select (exists (select 1 from tbl_names where Name = 'Lisa')) as flag
This will not fix the problem that you describe -- but it will always return one row with a single column whose value is 0 or 1.
'Lisa' is not in the table. You might try where Name like '%Lisa%'.
i have a table named FullSchedule and it contains teachers names and days and times within each day, and i want to write a Query as the following question
select all fields from FullSchedule, if the teacher's name = 'SomeName' then add a column called Check with the value 'Found' else if not found put the value 'Not Found'
what is the correct Query for this question ? notice that the teacher's column contains different names but i want to check for one of them. simply making a schedule for each teacher.
I would have that column in my table with a predefined value, let's say it's 'Not found' or 'Not checked' and then I would set that variable with a query of the type:
UPDATE table_name
SET column1 = value1, column2 = value2...., columnN = valueN
WHERE [condition];
If that doesn't fit your needs, you can try a set query from a query or something like this
I've been using VBA to examine all the queries, forms, and modules in my Access 2000 database, but it can be quite tedious and slow. Recently, I decided to take a closer look at the system tables in Access, in particular, MSysQueries and MSysObjects. Can I use these tables to examine my objects in the database faster? Of course, these tables are read-only, so I can't make any modifications to the database through them without returning to VBA. What do the attributes in MSysQueries mean?
Well, I came across this post on Google groups. I did further investigation on my own tables and wanted to share a table of information that I created inspired by work already done.
Each query can take up multiple rows in the table.
The row with attribute 0 is the beginning of the query.
The row with attribute 1 indicates the type of the query.
Flag value 1 = SELECT query.
Flag value 2 = SELECT ... INTO query, or a make table query. Name1 will have the name of the table that is created.
Flag value 3 = INSERT query; Name1 will have the name of the table to insert to.
Flag value 4 = UPDATE query
Flag value 5 = DELETE query
Flag value 6 = Crosstab query (TRANSFORM)
Flag value 9 = UNION query
The rows with attribute 2 (there could be multiple) are each formal parameter of the query. The Flag column indicates the data type (i.e. "10" for dbText) and the Name1 column indicates the name of the parameter. If there are no rows with attribute 2, then the query does not have formal parameters.
The row with attribute 3 indicates the presence of UNION or DISTINCT keywords.
Flag value 0 = Nothing special
Flag value 1 = UNION ALL
Flag value 2 = SELECT DISTINCT
Flag value 3 = UNION
Flag value 8 = SELECT DISTINCTROW
Flag value 9 = Queries on master fields and child fields
The row with attribute 4 indicates if the query comes from an external database. Name1 will contain the source if attribute 4 exists.
The rows with attribute 5 (there could be multiple) indicate each table found in the query. If the query is a UNION query, the Expression field has a split on the UNION keyword and the Name2 field has a system-generated table alias. For all other tables in a query, Name1 is the name of the table and Name2 is the alias, if there is one.
The rows with attribute 6 (there could be multiple) indicate each single field or expression in the query. If there is no attribute 6 for the query, the behavior assumed is that all fields are included. The Expression field contains each field expression or name, and Name1 contains the field alias if there is one.
Flag value 0 = Value of the field or expression
Flag value 1 = The field is a column heading in a crosstab query.
Flag value 2 = The field is a row heading in a crosstab query.
The rows with attribute 7 (there could be multiple) indicate each single join "ON" expression. The Expression field contains the actual join expression. Name1 contains the first table in the join. Name2 contains the second table in the join.
Flag value 1 = Inner Join
Flag value 2 = Left Join
Flag value 3 = Right Join
The row with attribute 8 contains the whole WHERE clause in the Expression field. If there is no where clause, attribute 8 is omitted from the query.
The rows with attribute 9 (there could be multiple) indicate each single Group By expression in the GROUP BY clause of the query. The Expression field contains each group by expression.
Flag value 0 = Value of the field or expression
Flag value 1 = The field is a column heading in a crosstab query.
Flag value 2 = The field is a row heading in a crosstab query.
The rows with attribute 11 (there could be multiple) indicate each single Order By expression in the ORDER BY clause of the query. The Expression field contains each order by expression. Name1 has "D" or "d" to indicate that the sort is done in descending order.
The row with attribute 255 is the end of the query.
I'm not exactly sure what the Order field does, but I did find that it is not Null, and though it sometimes has a value of an empty string, it doesn't always have that value. Empty strings occur on attributes 5, 6, 7, and 9, but it is not always an empty string for those attributes.
Thanks to #Bobort great explanations, I was able to create a query that lists all queries in current database, with their input tables/queries, query type, and target table (for action queries).
I thought I could share that here.
SELECT MSysObjects.Name AS queryName,
Mid("SelectMakTblAppendUpdateDeleteXtab 777777PassThUnion ",([msysqueries]![Flag]-1)*6+1,6) AS queryType,
src.Name1 AS [Input],
MSysQueries.Name1 AS Target
FROM (MSysQueries INNER JOIN MSysObjects ON MSysQueries.ObjectId = MSysObjects.Id)
LEFT JOIN (select * from MSysQueries WHERE Attribute = 5 ) AS src
ON MSysQueries.ObjectId = src.ObjectId
WHERE (((MSysObjects.Name)>"~z") AND ((MSysQueries.Attribute) =1))
ORDER BY MSysObjects.Name, src.Name1;
To use, just create a query in SQL view and paste the above code.
Further to Bobort and iDevlop's answers:
The row with attribute 1 indicates the type of the query.
Flag value 7 = DDL Query (eg CREATE TABLE...)
Flag value 9 = Pass through Query
The row with attribute 3 indicates the predicate.
Flag value 1 = All values, or UNION ALL (if a UNION query)
Flag value 4 = WITH OWNERACCESS OPTION
Flag value 16 = TOP N
Flag value 48 = TOP N PERCENT
The rows with attribute 5 (there could be multiple) indicate each FROM table/query found in the query
Expression contains the FROM source, or the SELECT statement if a UNION query
The row with attribute 10 contains the whole HAVING clause in the Expression field. If there is no HAVING clause, attribute 10 is omitted from the query.
The Order field is a BIG-ENDIAN binary value that contains an array of 4 bytes (binary fields can be added with VBA, but cannot be added using the UI, unless you copy and paste from a binary field in a system table.) However, in most databases, in the MSysQueries table, you're unlikely to encounter binary values greater than 255, so you can shortcut the conversion to a byte by inspecting the byte at index 3. For example:
Sub EnumOrder()
Dim rst As Recordset
Set rst = CurrentDb.OpenRecordset( _
" SELECT * FROM MSysQueries " & _
" WHERE Attribute = 6 " & _
"ORDER BY ObjectId Asc, [Order] Asc")
With rst
Do While Not .EOF
Debug.Print .Fields("ObjectId"), .Fields("Order")(3)
.MoveNext
Loop
.Close
End With
End Sub
Cumulative values occur for Attribute 3. So additional items include:
Flag 12 SELECT DISTINCT.... WITH OWNERACCESS OPTION
Flag 18 SELECT DISTINCT TOP (i.e. 2+16)
Flag 24 SELECT DISTINCTROW TOP (i.e. 8+16)
Flag 50 SELECT DISTINCT TOP PERCENT (i.e. 2+48)
Flag 56 SELECT DISTINCTROW TOP PERCENT (i.e. 8+48)
I have written an extended article about the workings of the MSysQueries table. See How Access stores queries.
My query is like this
select 5 from mytable_name;
Then the output is like column name 5 and the value is 5 printing as many max number of rows exists in that table.
Can anybody tell the reason why this query is working like this?
Can anybody tell the reason why this query is working like this?
You are selecting a string literal value '5' for each row in your table:
select 5 from mytable_name;
And this works fine. Because in the SELECT statement you can select:
Column reference,
Literal value like in your case.
Function.
value expression.
Select expression.
As defined by the standard SQL1:
Update:
However, If you have a column with a name is a number like in your case, you have to escape it in order to select the values in it like so:
SELECT `143` FROM Table1;
This will select all the rows in the column 143.
But, this:
SELECT 143 FROM Table1;
Will select the string literal 143 for each row found in the table.
Note that: If possible, try not to name these columns this way, it is recommended and a best practice, not to do this.
SQL Fiddle Demo
Update 2:
Note that, if you select 143 or '143', or even "143" this will select the literal value 143 not the column date. The following are the same:
SELECT 143 FROM Table1;
SELECT '143' FROM Table1;
SELECT "143" FROM Table1;
All these SELECTs won't select the data in the column, They will select the literal value 143 not the column data. See this demo:
Demo
You have to escape the column name with the two:
``
Like this:
SELECT `143` FROM table1;
Not:
SELECT '143' FROM table1'
Like what I did here:
The right Demo
1Image From: SQL Queries for Mere Mortals
from mytable
will select all rows from your table if there is no where condition that shrinks that result. and
select 5
will select the constant number 5 for every record. If you use a column name in the select part then that value will be selected for every record.
The DB engine will name the result 5 because it automatically generates a column name and 5 is the logical name for that.
You want 'SELECT * FROM mytable_name LIMIT 0,5' perhaps?
Since you don't have anything in your where clause, it is selecting all the rows from your table. The fact that you don't select any of the columns is irrelevant - you'll still get a result for each row in the table.
With the command select 5 ... you are viewing a fixed value. Same thing you run the following command: select "test", you will be displaying a fixed string.
Using ... from mytable_name you're looking for all record of this table.
With this we can conclude that for each record in the table mytable_name shows you the fixed value "5".