In a SQL query, that contains
... WHERE MYID = #1 ....
I have to manage 2 cases
1) There is a filter on a column, #1 will be a number (1,2,X...)
2) There is no filter on that column, #1 will be ...? (ANY)
Is there something for this "any" (SQL Server 2005) ?
PS.
Obviously, I understand that I can remove the "where".
PPS.
I explain myself for better understanding: I have this query in the code, and would like to pass an integer as parameter when the filter is ON, and "something" when my filter is OFF.
if (filterOn)
GetFoos(fooID);
else
GetFoos("ANY");
GetFoos(param1): "select * from FOOS where FOOID = {0}", param1
Make a UNION ALL of the two statements:
SELECT *
FROM mytable
WHERE myid = #col
UNION ALL
SELECT *
FROM mytable
WHERE #col IS NULL
or just split them in an IF / ELSE block of a stored procedures.
Either way, the optimizer will be able to optimize the queries separately, completely ignoring one of them depending on the value of #col.
you could do something along this line:
where (myid = #id or #id is null)
so you will only filter when #id contains a value and not when it is null.
Just remove the where or and clause if there is no filter on that column.
If you don't want to filter on a particular column, just don't filter on that column. Remove the WHERE MYID = entirely
Having
"select * from FOO where FOOID = {0}", param
use param="FOOID" when there is no param to filter, this will give
select * from FOO where FOOID = FOOID // removing the filter
Related
I'm just taking a look at the following query
select * from tablename
where id like '%%';
So that it can handle parameters to include all of the data or filtered data like bellow
select * from tablename
where id like '%1%';
Which is fine for most parameters I use but this seems wrong for an ID because it will return all data that has IDs containing 1 which I don't want
To get around this I can only append the where clause if the ID is given but that seems like a pain in the butt
Is it possible to use a different type of where clause so that a wildcard can be used in a where equals clause instead of a where like clause, example
select * from tablename
where id = '*';
So that the same query can be used to return all or filtered data? Pass parameter '*' for all or parameter '1' for ID 1 specifically
(I'm not sure if it matters for this case but I'm using PostgreSQL 9.6.12 in this example)
This would often be expressed as:
where (id = :id or :id is null)
null is the "magic" value that represents all rows.
I got a table Table(id,name), but lets just work with id here
id
--
A
B
C
D
all
What I want is to select all rows (A,B,C D...) except 'all' if the input is all, otherwise only the specific value ( e.g.: A if the input is A ).
Do you guys have some tasty-juicy solution for this one? Thanks!
Let's say you have a parameter #Id in your query. Then you can formulate your WHERE clause based on #Id's value:
SELECT *
FROM MyTable t
WHERE i.Id <> 'all' AND (#Id='all' OR #Id=t.Id)
i.Id <> 'all' part ensures that 'all' row is never returned, regardless of the setting of #Id. The rest is your condition translated to SQL (i.e. either the query has 'all', or the query matches a single Id).
This looks like the wrong usage of a relational table as the "id" column should contain only ids...
I suggest removing the "all" row and instead write a stored procedure to decide whether to select all rows or just one.
Anyway, for your example:
SELECT * FROM your_table WHERE (id = #ID OR #ID = 'all') AND id <> 'all'
My Db look like this:
id | Column1 | Column2
Must known facts: id is not a primary unique id (but could be). id can go up to 2Millions+. Column values are filled with TINYINT
var query : String = "SELECT Column1 FROM Table1 WHERE Column1 <> 0";
dbcmd = dbcon.CreateCommand();
dbcmd.CommandText = query;
reader = dbcmd.ExecuteReader();
var result : int = 0;
while(reader.Read()) {
result++;
}
return result;
But for a basic search it makes up to 5 seconds, is there anyway to make it faster?
Edit: Like always, thanks for the contributors and the rapidity!
Yes, you are reading your results and processing them one by one. All you seem to be doing to need is the count, which you can get with:
"SELECT COUNT(*) FROM Table1 WHERE Column1 <> 0";
This doesn't look like javascript code, but you could try counting the records instead of executing the query and then looping through the entire resultset on the client and increment a variable:
var query : String = "SELECT Count(Column1) FROM Table1 WHERE Column1 <> 0";
This will be much faster than your code because the count operation will be done by the database server directly.
Yes, index the table on Column1, the row used in the where clause.
consider a query that looks something like this:
my $query=<<QUERY;
select * from foo1 where col < ?
union all
select * from foo2 where col < ?
QUERY
Assume that the actual query really needs unions and can't be efficiently solved another way. The variable in the where clause will always be the same. Is there any way I can structure this so that I only need to pass 1 argument to execute instead of passing the same argument twice?
Could try the following, I'm assuming you're passing an integer to the where clause...
DECLARE #variableName as int
SET #variableName = ? --the value gets passed here once
select * from foo1 where col < #variableName -- and gets used here
union all
select * from foo2 where col < #variableName -- and here!
You could use the list repetition operator.
$sth->execute(($value) x 2);
In "real" databases, you can parameterize a query and pass in the query as an argument. Here is an alternative solution:
with const as (select ? as val)
select *
from ((select foo1.*
from foo1 cross join const
where col < const.val
) union all
(select foo2.*
from foo2 cross join const
where col < const.val
)) t
I am not suggesting that this is necesarily a good idea. However, I have at times found it quite useful to gather parameters into such a subquery and then join them in where needed.
i have a procedure in which the below condition is to be written in a WHERE clause. How do I do that.
itemid is a parameter which can be null.
if itemid is available then add it to my where clause,else do nothing
Some people use this technique
... WHERE #itemid IS NULL OR tbl.itemid = #itemid
It guarantees though that you will never get an index seek on the itemid column.
A better approach if the table is at all big is to split the query up into 2 separate cases
IF(#itemid IS NULL)
SELECT foo FROM bar
ELSE
SELECT foo FROM bar WHERE itemid = #itemid
If the number of combinations is too large you can consider dynamic SQL. Be sure you understand SQL injection first.
Ref: Dynamic Search Conditions in T-SQL
e.g.
SELECT Something
FROM SomeTable
WHERE (#MyParam IS NULL OR SomeField = #MyParam)
AND AnotherField = 1
You'll want to test this in your specific scenario for performance. If it's a simple query i.e. without a lot of conditional parameters, you might want to try this instead for performance:
IF ( #MyParam IS NULL )
SELECT Something
FROM SomeTable
WHERE AnotherField = 1
ELSE
SELECT Something
FROM SomeTable
WHERE SomeField = #MyParam
AND AnotherField = 1