Select default if no rows return - sql

SELECT Column1
FROM Table1
WHERE PKColumn = SomeValue
I am selecting just one column, my query will return only 0 or 1 row for sure. I want to select some default values like Some Default if no row returned otherwise the returned value.
I tried something like
SELECT CASE WHEN COUNT(1) = 1 THEN Column1 ELSE 'Some Default' END AS Column1
FROM Table1
WHERE PKColumn = SomeValue
GROUP BY Column1
But it doesn't work.
Is there any way to do it in single SQL statement?

I think you can use a query like this:
SELECT TOP(1)
CASE WHEN EXISTS(SELECT 1 FROM t WHERE PKColumn = SomeValue) THEN Column1
ELSE 'Some Default' END AS Column1
FROM t;
Or using EXISTS with UNION:
SELECT 'Some Default' As Column1
WHERE NOT EXISTS(SELECT 1 FROM t WHERE PKColumn = SomeValue)
UNION ALL
SELECT Column1
FROM t
WHERE PKColumn = SomeValue;

You can use COALESCE
Evaluates the arguments in order and returns the current value of the
first expression that initially does not evaluate to NULL.
SELECT COALESCE((SELECT TOP 1 Column1 FROM Table1 WHERE PK = SomeValue), 'DefaultValue')
or like this:
DECLARE #ReturnValue INT = 3 -- Default value
SELECT TOP 1 #ReturnValue = Column1 FROM Table1 WHERE PK = SomeValue
SELECT #ReturnValue

SELECT
[Column1] = ISNULL([t2].[Column1], 'Some Default')
FROM
[Table1] AS [t1]
OUTER APPLY
(
SELECT
[Column1]
FROM
[Table1]
WHERE
[PKColumn] = [t1].[PKColumn]
) AS [t2]
WHERE
[t1].[PKColumn] = 'SomeValue';

Perhaps can try using LEN instead of COUNT to check if Column1 has value?
SELECT CASE WHEN LEN(Column1) > 0 THEN Column1 ELSE 'Some Default' END AS Column1
FROM Table1
WHERE PKColumn = SomeValue
GROUP BY Column1

Related

IF ELSE in where block of sql query

I have the below stored procedure
CREATE PROCEDURE sp1
(
#param1 bit,
#parma2 bit
)
AS
BEGIN
SELECT * from Table1 where
if #param1 = 1 then column1 is null
else if #parma2 = 1 then column1 is not null
END
Obviously the If else part in the where clause is not correct . Could anyone suggest how to tackle it ?
Something like this:
SELECT * from Table1 where
case
when #param1 = 1 then [column 1] is null
when #param2 = 1 then [column 1] is not null
end
But you don't need two parameters for this procedure, only one should suffice.
Try the following:
SELECT
Case WHEN #param1 = 1 THEN Null
Case WHEN #param2 = 1 THEN column1 Else '' End as column1 ,
* FROM Table1
The above statement will set column1 to null if param1 = 1, it will get the value of column1 if param2 = 1 otherwise it will set it to empty string.
Seems to me like the simplest option would be to use AND and OR:
SELECT *
FROM Table1
WHERE (#param1 = 1 AND column1 is null)
OR (#parma2 = 1 AND column1 is not null)
Use this:
CASE WHEN condition THEN value ELSE value END

Get row from table based on parameter

I want to get row from based on parameter value. Either it could be value 'ABC' or NULL. Below is the source table and expected result, which I'm trying to achieve.
SourceTable
column1 column2
--------------------------
value1 NULL
value2 ABC
Tried with query, but it is getting two rows which are with value1 and value2.
Declare #Param1 varchar(20) = 'ABC'
Select *
from SourceTable
where column2 = #Param1 Or column2 is NULL
If value is 'ABC' then Result -
column1 column2
--------------------------
value2 ABC
If value is NULL then Result -
column1 column2
--------------------------
value1 NULL
Perhaps this would work for you?
select *
from SourceTable
where column2 = #Param1 or (#Param1 is null and column2 is null)
You can try something like: Only problem you might encounter with this is if your column2 has blanks.
SELECT *
FROM SourceTable
WHERE ISNULL(column2, '') = ISNULL(#Param1, '')
Perhaps you want union all and a check for existence:
Select *
from SourceTable
where column2 = #Param1
union all
Select *
from SourceTable
where column2 is null and not exists (select 1 from sourcetable st2 where st2.column2 = #Param1);
An alternative uses order by -- if you want only one row:
select top 1 st.*
from sourcetable st
where column2 = #param1 or column2 is null
order by (case when column2 is not null then 1 else 2 end);

How do I create a conditional WHERE clause?

I need to have a conditional where clause that operates as so:
Select *
From Table
If (#booleanResult)
Begin
Where Column1 = 'value1'
End
Else
Begin
Where column1 = 'value1' and column2 = 'value2'
End
Any help would be appreciated.
Could you just do the following?
SELECT
*
FROM
Table
WHERE
(#booleanResult = 1
AND Column1 = 'value1')
OR
(#booleanResult = 0
AND Column1 = 'value1'
AND Column2 = 'value2')
You can group conditions easily in a WHERE clause:
WHERE
(#BooleanResult=1 AND Column1 = 'value1')
OR
(#BooleanResult=0 AND Column1 = 'value1' AND column2 = 'value2')
Based on the script in question, it seems that you need the condition for Column1 irrespective of whether the variable #booleanResult is set to true or false. So, I have added that condition to the WHERE clause and in the remaining condition checks whether the variable is set to 1 (true) or if it is set to 0 (false) then it will also check for the condition on Column2.
This is just one more way of achieving this.
Create and insert script:
CREATE TABLE MyTable
(
Column1 VARCHAR(20) NOT NULL
, Column2 VARCHAR(20) NOT NULL
);
INSERT INTO MyTable (Column1, Column2) VALUES
('value1', ''),
('', 'value2'),
('value1', 'value2');
Script when bit variable is set to 1 (true):
DECLARE #booleanResult BIT
SET #booleanResult = 1
SELECT *
FROM MyTable
WHERE Column1 = 'value1'
AND ( #booleanResult = 1
OR (#booleanResult = 0 AND Column2 = 'value2')
);
Output:
COLUMN1 COLUMN2
------- -------
value1
value1 value2
Script when bit variable is set to 0 (false):
DECLARE #booleanResult BIT
SET #booleanResult = 0
SELECT *
FROM MyTable
WHERE Column1 = 'value1'
AND ( #booleanResult = 1
OR (#booleanResult = 0 AND Column2 = 'value2')
);
Output:
COLUMN1 COLUMN2
------- -------
value1 value2
Demo:
Click here to view the demo in SQL Fiddle.
To provide a shorter answer:
Select *
From Table
Where Column1 = 'value1' and
coalesce(column2, '') = (case when #BooleanResults = 0
then 'value1'
else coalesce( column2, '')
end)
Query 1: if the #CompanyID is set to -1 then all records are selected
Query 2: if the #CompanyID is set to 10 or 11 or 12, only those records are selected where the companyid=#CompanyID
Declare #CompanyID int
Set #CompanyID = -1
select * from sales
where 1=IIF(#CompanyID =-1, 1, IIF(CompanyID =#CompanyID,1,0))
Set #CompanyID = 10
select * from sales
where 1=IIF(#CompanyID =-1, 1, IIF(CompanyID =#CompanyID,1,0))

Execute queries until non-empty result

I have three queries, looking like these:
SELECT * FROM Table1 WHERE Column1 = 'a'
SELECT * FROM Table2 WHERE Column2 = 'b'
SELECT * FROM Table1 A, Table2 B WHERE A.Column1 <> B.Column1
Now all logic is implemented on the client side as following. Execute the first query, if HasRows, set a flag to 1 and return the rows. Otherwise execute the second query, if HasRows, set the flag to 2 and return the rows. Otherwise execute the third query, set the flag to 3 and return the rows.
How to do this with a single query? Flag stuff, I guess, should be solved adding Flag to the queries:
SELECT Flag = 1, * FROM Table1 WHERE Column1 = 'a'
SELECT Flag = 2, * FROM Table2 WHERE Column2 = 'b'
SELECT Flag = 3, * FROM Table1 A, Table2 B WHERE A.Column1 <> B.Column1
But now what? How to check, if a query returns non-empty result?
Also, I'd like to cache the results, in other words, to avoid executing the same query twice - once for checking and the second time - for returning data.
Regards,
You could use a table variable to store the result and only return it at the end of the SQL block. Checking ##rowcount would tell you if the previous insert added any rows; if it's zero, you can run further queries:
declare #result table (flag int, col1 int, col2 varchar(50))
insert #result select 1, col1, col2 from Table1 where Column1 = 'a'
if ##rowcount = 0
begin
insert #result select 2, col1, col2 from Table2 where Column1 = 'b'
end
if ##rowcount = 0
begin
insert #result select 3, col1, col2 from Table1 A, Table2 B
where A.Column1 <> B.Column1
end
select * from #result
This approach only works if each select has the same column definition.

IF statement error

I have the following columns in TableA
TableA
Column1 varchar
Column2 int
Column3 bit
I am using this statement
IF Column3 = 0
SELECT Column1, Column2 FROM
TableA WHERE
Column2 > 200
ELSE
SELECT Column1, Column2 FROM
TableA WHERE
Column2 < 200
But the statment does not compile. It says Invalid Column Name 'Column3'
Column3 is not being referenced anywhere outside of the IF and ELSE blocks. If you wish to reference this value you will need to declare a new variable and use that;
DECLARE #btColumn3 BIT
SELECT #btColumn3 = Column3 FROM #tblTableA
IF #btColumn3 = 0
SELECT Column1, Column2 FROM
#tblTableA WHERE
Column2 > 200
ELSE
SELECT Column1, Column2 FROM
#tblTableA WHERE
Column2 < 200
Or do the following;
IF (SELECT Column3 FROM #tblTableA) = 0
SELECT Column1, Column2 FROM
#tblTableA WHERE
Column2 > 200
ELSE
SELECT Column1, Column2 FROM
#tblTableA WHERE
Column2 < 200
Either way you will have to ensure that the query used to retrieve Column3 returns a single result either by limiting your query so that it can only return a single value or using MIN(), MAX() etc depending on your requirements.
Also, if you need to execute more than one query within the IF and ELSE blocks you will need to wrap the contents in BEGIN and END as follows:
IF #btColumn3 = 0
BEGIN
// Do a query
// Do another
END
ELSE
BEGIN
// Do a query
// Do another
END
If you want to do this you need to first store the value of Column3 in a variable.
Declare #temp money
Select #Temp = Column3
From TableA
IF #Temp = 0
begin
SELECT Column1, Column2 FROM
TableA WHERE
Column2 > 200
end
ELSE
begin
SELECT Column1, Column2 FROM
TableA WHERE
Column2 < 200
end
Obviously, this assumes that there will only be one value returned for Column3.
EDIT:
This is a different approach which I think should work for you:
declare #CutOffValue money
declare #MaxValue money
Set #CutOffValue = 200
Set #MaxValue = 9999999999
Select Column1, Column2
From TableA
Where Column2 > Case When Column3 = 0 Then #CutOffValue Else 0 End
And Column2 < Case When Column3 = 0 Then #MaxValue Else #CutOffValue End
You are mixing 2 different levels:
IF is at the TSQL (procedure) level and cannot depend on the row values
SELECT is the query itself where the row values can be used to filter the result set
The following would work
IF Condition /* independent of the different values of TableA. can be an aggregate though */
BEGIN
SELECT Column1, Column2 FROM
TableA WHERE
Column2 > 200
END
ELSE
BEGIN
SELECT Column1, Column2 FROM
TableA WHERE
Column2 < 200
END
You will need the syntax as follows
IF <CONDITION>
BEGIN
<Your Statement>
END
ELSE
<Your Statement>
Hope this is helpful!!
Assuming you have posted the complete query, then the problem with your IF clause is that you are assuming that it can use the columns from the SELECT statement following it. It cannot and does not. This is why it will not compile.
You need your test condition to be separate from the statements following the IF clause. See on MSDN.
DECLARE #test BIT
SELECT #test = 0
IF #test = 0
BEGIN
SELECT Column1, Column2 FROM
TableA WHERE
Column2 > 200
END
ELSE
BEGIN
SELECT Column1, Column2 FROM
TableA WHERE
Column2 < 200
END
Why not just do
select Column1, Column2 from TableA where
Column2 > 200 and Column3 = 0 or Column2 < 200 and Column3 = 1
or, abusing arithmetics,
select Column1, Column2 from TableA where (Column2 - 200) * (2 * Column3 - 1) < 0
Since the answer to your problem varies largely on exactly what logic has to be implemented, analyzing present scenario all I can give you is a small and compact query which can meet your requirements (I hope so…)
SELECT Column1,column2 FROM TableA WHERE
(CASE WHEN Column3=0 then Column2 else 2)>(CASE WHEN Column3=0 then 200 ELSE 1)
AND (CASE WHEN Column3<>0 then Column2 else 1)<(CASE WHEN Column3<>0 then Column2 else 2)