How can you query a column for any value in that column? (ie. How do I build a dynamic where clause that can either filter the value, or not.)
I want to be able to query for either a specific value, or not. For instance, I might want the value to be 1, but I might want it to be any number.
Is there a way to use a wild card (like "*"), to match any value, so that it can be dynamically inserted where I want no filter?
For instance:
select int_col from table where int_col = 1 // Query for a specific value
select int_col from table where int_col = * // Query for any value
The reason why I do not want to use 2 separate SQL statements is because I am using this as a SQL Data Source, which can only have 1 select statement.
Sometimes I would query for actual value (like 1, 2...) so I can't not have a condition either.
I take it you want some dynamic behavior on your WHERE clause, without having to dynamically build your WHERE clause.
With a single parameter, you can use ISNULL (or COALESCE) like this:
SELECT * FROM Table WHERE ID = ISNULL(#id, ID)
which allows a NULL parameter to match all. Some prefer the longer but more explicit:
SELECT * FROM Table WHERE (#id IS NULL) OR (ID = #id)
A simple answer would be use: IS NOT NULL. But if you are asking for say 123* for numbers like 123456 or 1234 or 1237 then the you could convert it to a varchar and then test against using standard wild cards.
In your where clause: cast(myIntColumn as varchar(15)) like '123%'.
Assuming the value you're filtering on is a parameter in a stored procedure, or contained in a variable called #Value, you can do it like this:
select * from table where #Value is null or intCol = #Value
If #Value is null then the or part of the clause is ignored, so the query won't filter on intCol.
The equivalent of wildcards for numbers are the comparators.
So, if you wanted to find all positive integers:
select int_col from table where int_col > 0
any numbers between a hundred and a thousand:
select int_col from table where int_col BETWEEN 100 AND 1000
and so on.
I don't quite understand what you're asking. I think you should use two different queries for the different situations you have.
When you're not looking for a specific value:
SELECT * FROM table
When you are looking for a specific value:
SELECT * FROM table WHERE intcol = 1
You can use the parameter as a wildcard by assigning special meaning to NULL:
DECLARE #q INT = 1
SELECT * FROM table WHERE IntegerColumn = #q OR #q IS NULL
This way, when you pass in NULL; you get all rows.
If NULL is a valid value to query for, then you need to use two parameters.
If you really want the value of your column for all rows on the table you can simply use
select int_col
from table
If you want to know all the distinct values, but don't care how many times they're repeated you can use
select distinct int_col
from table
And if you want to know all the distinct values and how many times they each appear, use
select int_col, count(*)
from table
group by int_col
To have the values sorted properly you can add
order by int_col
to all the queries above.
Share and enjoy.
Related
I have following query which uses coalesce to return the id of a calendar with a specific code
SELECT COALESCE(SD_CALENDAR.ID,0) FROM SD_CALENDAR WHERE SD_CALENDAR.CODE = 'BOER';
But when I run this I get a blank column as result, instead of 0. What do I need to change to make my query work?
You said that no rows in your table match your query, so you are trying to return 0 when there is no match, rather than returning no data at all.
If NAME is unique then you could use an aggregate to achieve this:
SELECT COALESCE(MAX(SD_CALENDAR.ID),0) FROM SD_CALENDAR WHERE SD_CALENDAR.CODE = 'BOER';
The MAX() will always return one row; if there is a match it will be the single ID anyway, and if there isn't it will be null - which you can then coalesce to zero.
If NAME isn't unique and you expect multiple values back then you can use a union to provide the zero value when there is no match:
SELECT COALESCE(SD_CALENDAR.ID,0) FROM SD_CALENDAR WHERE SD_CALENDAR.CODE = 'BOER'
UNION ALL
SELECT 0 FROM DUAL WHERE NOT EXISTS (
SELECT COALESCE(SD_CALENDAR.ID,0) FROM SD_CALENDAR WHERE SD_CALENDAR.CODE = 'BOER'
);
Depending on what you're doing, it might be better/easier to let your application handle a no-data-found result and substitute a zero itself.
I have a stored procedure which takes in five parameters of which two can be null - we will call these parameters A and B
What I would like to do is select records based on the following logic.
If Parameter A is NULL then only return records that match Parameter B
I know that I can do something similar to the following
IF A IS NULL
BEGIN
SELECT * FROM TABLE WHERE Param=B
END
ELSE
BEGIN
SELECT * FROM TABLE WHERE Param=A
END
However, the SQL query is much more complex then the above one and there would be huge replication in the Proc which is something I want to avoid
Thanks in advance
===============================
EDIT - Sorry, I should have mentioned that in the example the Param are based on separate columns e.g.
My table consists of four columns of which two separate columns map to the two parameters - basic schema below
ID
PersonName
GroupID
DeliveryID
In my procedure I want to retrieve those records that match the GroupID however in the scenario where the GroupID is null then I want to return those records that match the DeliveryID
Thanks again
Try
SELECT * FROM my_table WHERE Param = COALESCE(A,B)
COALESCE will give you A if it's not null. Otherwise B.
Functionally, something like this should work. If either parameter is NULL, the condition becomes a self-identity (assuming neither groupID nor deliveryID is NULL).
SELECT *
FROM table_name
WHERE groupID = coalesce(#groupIDParameter, groupID)
AND deliveryID = coalesce(#deliveryIDParameter, deliveryID)
Try ISNULL function:
SELECT * FROM TABLE WHERE Param = ISNULL(B,A)
You could also use a case statement Case when A is Null Then B
Let's say that we have a table named Data with Id and Weather columns. Other columns in that table are not important to this problem. The Weather column can be null.
I want to display all rows where Weather fits a condition, but if there is a null value in weather then display null value.
My SQL so far:
SELECT *
FROM Data d
WHERE (d.Weather LIKE '%'+COALESCE(NULLIF('',''),'sunny')+'%' OR d.Weather IS NULL)
My results are wrong, because that statement also shows values where Weather is null if condition is not correct (let's say that users mistyped wrong).
I found similar topic, but there I do not find appropriate answer.
SQL WHERE clause not returning rows when field has NULL value
Please help me out.
Your query is correct for the general task of treating NULLs as a match. If you wish to suppress NULLs when there are no other results, you can add an AND EXISTS ... condition to your query, like this:
SELECT *
FROM Data d
WHERE d.Weather LIKE '%'+COALESCE(NULLIF('',''),'sunny')+'%'
OR (d.Weather IS NULL AND EXISTS (SELECT * FROM Data dd WHERE dd.Weather LIKE '%'+COALESCE(NULLIF('',''),'sunny')+'%'))
The additional condition ensures that NULLs are treated as matches only if other matching records exist.
You can also use a common table expression to avoid duplicating the query, like this:
WITH cte (id, weather) AS
(
SELECT *
FROM Data d
WHERE d.Weather LIKE '%'+COALESCE(NULLIF('',''),'sunny')+'%'
)
SELECT * FROM cte
UNION ALL
SELECT * FROM Data WHERE weather is NULL AND EXISTS (SELECT * FROM cte)
statement show also values where Wether is null if condition is not correct (let say that users typed wrong sunny).
This suggests that the constant 'sunny' is coming from end-user's input. If that is the case, you need to parameterize your query to avoid SQL injection attacks.
This may be simple, but I am no SQL whiz so I am getting lost. I understand that sql takes your query and executes it in a certain order, which I believe is why this query does not work:
select * from purchaseorders
where IsNumeric(purchase_order_number) = 1
and cast(purchase_order_number as int) >= 7
MOST of the purchar_order_number fields are numeric, but we introduce alphanumeric ones recently. The data I am trying to get is to see if '7' is greater than the highest numeric purchase_order_number.
The Numeric() function filters out the alphanumeric fields fine, but doing the subsequent cast comparison throws this error:
Conversion failed when converting the nvarchar value '124-4356AB' to data type int.
I am not asking what the error means, that is obvious. I am asking if there is a way to accomplish what I want in a single query, preferably in the where clause due to ORM constraints.
does this work for you?
select * from purchaseorders
where (case when IsNumeric(purchase_order_number) = 1
then cast(purchase_order_number as int)
else 0 end) >= 7
You can do a select with a subselect
select * from (
select * from purchaseorders
where IsNumeric(purchase_order_number) = 1) as correct_orders
where cast(purchase_order_number as int) >= 7
try this:
select * from purchaseorders
where try_cast(purchase_order_number as int) >= 7
have to check which column has numeric values only.
Currently, in a table every field is setted with nvarchar(max) Like tableName (field1 nvarchar(max),field2 nvarchar(max),field3 nvarchar(3)) and tableName has 25lac Rows.
But on manually Check Field2 Contain the numeric Values Only... How to Check With t-sql that in the Complete Column (Field2) has numeric Value or not/null value with Longest Length in the Column!
How do I select only 1 row in sybase without using rowcount? I don't have the privilege to set rowcount in sybase. Is there a way to select only 1 row?
For example:
select * from table where name = 'jack'
This returns two rows; how do I select only one row from the result set without using set rowcount?
Try the query:
SELECT TOP 1 * FROM mytable
WHERE name = 'jack'
As you might guess, this selects the TOP 1 matching results. If you wanted more (which you don't here) you could use any number (TOP 100 or TOP 1000, etc).
A more comprehensive example can be found on w3schools: http://www.w3schools.com/Sql/sql_top.asp
There seems to be a reason, why you're getting more than 1 row for "WHERE name = 'jack'", it looks as if the rows differ.
But if, the rows do not differ you can try adding "distinct":
SELECT DISTINCT * FROM TABLE WHERE name = 'jack'
or try with "GROUP BY" statement, then you should type explicitly all columns, eg.:
SELECT name FROM TABLE WHERE name = 'jack' GROUP BY name
if this is not what you wanted, can you paste here how the 2 rows look exactly?
If you want a single result, use 'GROUP BY' and 'HAVING column = max(column)'. Or replace max() with min().
This should work unless the max or min values are also not unique.