select COUNT and then condition SQL - sql

I have a condition which based on my Count result, it should skip or include a join in my query,to make short the story,how to implement such a thing in SQL:
select count(names) as rslt
if(rslt)>0 then
select......join tables
else
Select...
as you see I want to say if the count is >0 then do the join otherwise it should skip then join and go to the next line,how should I achieve this?

DECLARE #Name INT
SELECT
#Name = COUNT(names)
FROM Table
IF #Name > 0
BEGIN
PRINT 'Do somthing'
END
ELSE
PRINT 'Do something else'
END
Just change the PRINT statements to your query logic

If you want to check if a resulting query returns any row (>0) then you should use an IF with an EXISTS rather than using COUNT. EXISTS will make the SQL engine stop running once it finds at least 1 row, while COUNT will force to actually count all records.
IF EXISTS (SELECT 1 FROM YourTable WHERE names IS NOT NULL)
BEGIN
SELECT
YourColumn
FROM
Table1
INNER JOIN Table2 ON --...
END
ELSE
BEGIN
SELECT
YourColumn
FROM
Table1
END
If on the other hand you need to check a specific amount, then you will have to COUNT and assign to variable.
DECLARE #CountTotal INT = (SELECT COUNT(names) FROM YourTable)
IF #CountTotal > 100
BEGIN
SELECT
YourColumn
FROM
Table1
INNER JOIN Table2 ON --...
END
ELSE
BEGIN
SELECT
YourColumn
FROM
Table1
END

DECLARE #reslt integer
#reslt = select count(names)
if #reslt >0 then
select......join tables
You need to put it in a variable and then call it.

You can also use dynamic query like below:
DECLARE #SQL NVARCHAR(MAX);
SELECT #SQL = N'SELECT *
FROM T1 ' + CASE WHEN (SELECT COUNT(names) FROM table1) > 0 THEN +
' INNER JOIN T2 ON T1.Id = T2.Id ' ELSE '' END
PRINT #SQL
EXEC sp_executesql #SQL;

Use CASE function, something like this :
Select count(CustomerID),
CASE
WHEN count(CustomerID) > 30 THEN "The quantity is greater than 30"
WHEN count(CustomerID) = 30 THEN "The quantity is 30"
ELSE "The quantity is something else"
END
FROM Customers;

You Can try below method as well.
if((select count(Name) from tableName)>0)
begin
select 1
end
else
begin
select 2
end
No need to use one temp variable to store the count .

Related

How can I generate a sequence number in a empty table

I am trying to make a query that can generate the latest sequence number +1 to the new record in sql server.
let ignore the insert part first, I write a query like this:
SELECT 'asdf' AS col1, CASE WHEN EXISTS (SELECT pk_sales_inv_no FROM salesInvoice WHERE pk_sales_inv_no LIKE 'Q-ARF2206-%') THEN 1 ELSE 0 END AS EXPR1
It looks fine, when the record with same prefix exists, It return 1, else 0.
Because I have to process the current latest sequence number in the true value part, so I change my query with this to get the pk_sales_inv_no for the true part processing.
SELECT TOP (1) 'asdf' AS col1, CASE WHEN EXISTS (SELECT pk_sales_inv_no FROM salesInvoice WHERE pk_sales_inv_no LIKE 'Q-ARF2206-%') THEN 1 ELSE 0 END AS EXPR1 FROM salesInvoice WHERE (pk_sales_inv_no LIKE 'Q-ARF2206-%') ORDER BY pk_sales_inv_no DESC
Then problem happens, because the select result is totally empty, so It doesn't return the 1 or 0.
How can I improve it to work out with a empty select result.
You can write a simple scalar udf, if you need it in JOIN adapt it as a table value function.
I doubt that this is what you need, I think you want to get the number after the 2nd dash
IF OBJECT_ID (N'dbo.udf_lastSequence') IS NOT NULL
DROP FUNCTION dbo.udf_lastSequence
GO
CREATE FUNCTION dbo.udf_lastSequence (#invNo varchar(100))
RETURNS int
AS
BEGIN
DECLARE #lastInvNo VARCHAR(100)
DECLARE #search VARCHAR(100)
DECLARE #result int
SET #result = 0
SET #search = CONCAT(#invNo, '%');
SELECT TOP 1 #lastInvNo = pk_sales_inv_no
FROM salesInvoice
WHERE (pk_sales_inv_no LIKE #search)
ORDER BY pk_sales_inv_no DESC
IF #lastInvNo IS NOT NULL
SET #result = CAST(REPLACE(#lastInvNo, #invNo, '') AS INT);
return #result
END
GO
Try it with SELECT dbo.udf_lastSequence('Q-ARF2206-') WITHOUT the final % charter

Multiple conditions without using multiple if else in SQL

I have to write a program in SQL that has multiple conditions but I shouldn't write it with multiple if else (because of the cost that if has). I'm new in this field and I have no idea how else could I write it which would be better
here is my sample code:
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA= 'dbo' AND TABLE_NAME = 'Food_tbl')
BEGIN
IF NOT EXISTS (SELECT TOP 1 FID FROM dbo.Food_tbl)
BEGIN
INSERT INTO dbo.Food_tbl
SELECT *
FROM DataFoodView
END
ELSE IF (SELECT COUNT(*) FROM dbo.Food_tbl)=20
BEGIN
PRINT N'Table Exists'
SELECT *
FROM Food_tbl
END
ELSE IF (SELECT COUNT(*) FROM dbo.FoodSara_tbl)<>20
BEGIN
print N'there isnt 20'
INSERT INTO Food_tbl (Food_tbl.FID, Food_tbl.Fname, Food_tbl.Ftype, Food_tbl.Fcount, Food_tbl.Datetype, Food_tbl.Fdescription)
SELECT DataFoodView.*
FROM DataFoodView
LEFT JOIN FoodSara_tbl ON Food_tbl.FID = DataFoodView.FID
WHERE Food_tbl.FID IS NULL;
END
END
PS: I have at first check if the table is exits and if it hasn't any record insert all the data, if it has 20 records show the table, if the table doesn't have 20 records find the missing data then insert that.
First, the condition in the ELSE part isn't needed :
change
ELSE IF (SELECT COUNT(*) FROM dbo.FoodSara_tbl)<>20
BEGIN
to
ELSE
BEGIN
Next, you may regroup the two INSERT parts because having no element is also having else than 20 elements.
The result will be something like that :
IF EXISTS
(
SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA= 'dbo' AND TABLE_NAME = 'Food_tbl'
)
BEGIN
IF (SELECT COUNT(*) FROM dbo.Food_tbl)=20
BEGIN
PRINT N'Table Exists'
SELECT *
FROM Food_tbl
END
ELSE
BEGIN
print N'there isnt 20'
INSERT INTO Food_tbl (Food_tbl.FID, Food_tbl.Fname, Food_tbl.Ftype,
Food_tbl.Fcount, Food_tbl.Datetype, Food_tbl.Fdescription)
SELECT DataFoodView.*
FROM DataFoodView
LEFT JOIN FoodSara_tbl ON Food_tbl.FID = DataFoodView.FID
WHERE Food_tbl.FID IS NULL;
END
END
Not understood the exact requirement from the description what you have provided but just review the following logic
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA= 'dbo' AND TABLE_NAME = 'Food_tbl')
BEGIN
DECLARE #RCount INT
SELECT #RCount= COUNT(FID) FROM dbo.Food_tbl
IF #RCount=0
BEGIN
//Your Logic 1 (for inserting data since no records found)
END
ELSE
BEGIN
PRINT N'Table Exists'
IF #RCount=20
BEGIN
//Your Logic 2
END
ELSE
BEGIN
//Your Logic 3
END
END
END
Please explain the requirement in details or build your queries based on the requirement and add in place of Logic 1,2,3

How to write if exist statement that would run a different select depending if it exists or not

I am trying to convert a sql if exists statement into a SSRS valid format to run a report on CRM.
CRM report doesn't accept the report on upload if I have a if exists method, I'm having troubles figuring out what I can use in its place.
IF EXISTS(select * from dbo.FC where dbo.FC.ContactID in (select dbo.AV.so_contactid from dbo.AV))
begin
select [STATEMENT 1]
from dbo.AV CRMAF_so_AV join
dbo.FC c
on CRMAF_so_AV.so_contactid = c.ContactID;
end
else
begin
select [STATEMENT 2]
from dbo.AV CRMAF_so_AV join
dbo.FA c
on CRMAF_so_AV.so_contactid = c.AccountID;
end;
I want to be able to either run the select [STATEMENT 1] if the condition is true else I want to run select [STATEMENT 2]
I have managed to get this to work by doing a LEFT JOIN instead of a JOIN.
select [STATEMENT 1 + 2 all columns needed]
from dbo.AV CRMAF_so_AV
left join dbo.FC c on CRMAF_so_AV.so_contactid = c.ContactID;
left join dbo.FA a on CRMAF_so_AV.so_contactid = a.AccountID;
This now runs if its an account or a contact.
Try this -
You have to put your entire statement in #select1 and #select1.
declare #statement1 as varchar(max);
declare #statement2 as varchar(max);
SET #statement1 = 'SELECT 1'
SET #statement2 = 'SELECT 2'
IF EXISTS(select * from dbo.FC where dbo.FC.ContactID in (select dbo.AV.so_contactid from dbo.AV))
BEGIN
EXEC (#statement1)
END
ELSE
BEGIN
EXEC (#statement2)
END
Instead of using if exists can you not get a count of records that meet the criteria and then if its 1 or greater run a different query as apposed to if it was equal to 0.
let me know if I am missing something what you are trying to achieve.
sorry i am unable to put comments due to having a new account so my reputation is low.
I think you need something like this:
WITH PreSelection AS (
SELECT
AV.ID AS AVID,
(SELECT TOP(1) c.ContactID FROM dbo.FC c WHERE c.ContactID = AV.so_contactid) AS ContactID,
(SELECT TOP(1) c.ContactID FROM dbo.FA c WHERE c.AccountID = AV.so_contactid) AS AccountID
FROM dbo.AV
)
SELECT
AVID,
ISNULL(
CASE WHEN ContactID IS NULL
THEN (SELECT TOP(1) AccountName FROM dbo.FA WHERE FA.AccountID = AccountID)
ELSE (SELECT TOP(1) LTRIM(RTRIM(ISNULL(FirstName, '') + ' ' + ISNULL(LastName, ''))) FROM dbo.FC WHERE FC.ContactID = ContactID)
END, '') AS ContactName
FROM PreSelection
A few things to note:
When SSRS evaluates query it expects the resluts to always have the same structure in terms of column names and types.
So you CANNOT do something like this..
IF #x=#y
BEGIN
SELECT Name, Age FROM employees
END
ELSE
BEGIN
SELECT DeptID, DeptName, DeptEMpCOunt FROM departments
END
... as this will return different types and column names and column counts.
What you CAN DO is this..
DECLARE #t TABLE(resultType int, colA varchar(128), colB int, colC varchar(128), colD int)
IF #x=#y
BEGIN
INSERT INTO #t(resultType, colA, ColB)
SELECT 1 as resultType, Name, Age FROM employees
END
ELSE
BEGIN
INSERT INTO #t(resultType, colB, colC, colD)
SELECT 2 AS resultType, DeptID, DeptName, DeptEmpCount FROM departments
END
SELECT * FROM #t
Al we are doing is creating a table that can handle all variations of the data and putting the results into whatever columns can accommodate that data type.
This will always return the same data structure so SSRS will be happy, then you will need to handle which columns to display your data from based on what gets returned, hence why I added the result type to the results so you can test that from within the report.

Sql server Query : Conditional Select columns with top keyword

DECLARE #mode INT;
SELECT CASE
WHEN #mode = 0
THEN t.Column1,Count(t.Column2) as Column2
ELSE top 1 t.Column1,Count(t.Column2) as Column2
END
FROM Table1 t
--Where some list of parameters
Group by t.Column1,t.Column2
Please read the above sql statement carefully. I have requirement to evaluate the query by two modes without changing the body of the query ie. From,Where and Group clauses should be written only once and not to replicate them (each one) anywhere in the result query
if #mode = 0 then the above said columns should be returned, and
if #mode <> 0 then the "Top1" of records should be returned
Both select conditions use the same given set list of parameters.
When I run the above query am facing the error "Incorrect syntax near the keyword 'top'." because we could not use the top 1 keyword within conditional select statements and select condition's columns must be matched even with their datatypes.
I need to fix the above query without affecting logic of the query.
IF(#mode <= 0)
BEGIN
Select Column1,Count(t.Column2) as Column2
From Table1 t
Group by t.Column1,t.Column2
END
Else
BEGIN
Select top 1 *
From Table1 t
END
Or create a temporary table and load data using where condition
Create Table #Temp (Column1 datetype,Column2 datetype)
Insert Into #Temp (Column1,Column2)
Select Column1,Column2
From Table1 t
Where condition
IF(#mode <= 0)
BEGIN
Select Column1,Count(t.Column2) as Column2
From #Temp t
Group by t.Column1,t.Column2
END
Else
BEGIN
Select top 1 *
From #Temp t
END
BEGIN
DECLARE #mode INT;
SET #mode = 0;
IF #mode <= 0
SELECT t.Column1,count(t.Column2) as Column2 from Table_Name t
GROUP BY t.Column1,t.Column2
ELSE
SELECT TOP 1 t.Column1,count(t.Column2) as Column2 from Table_Name t
GROUP BY t.Column1,t.Column2
END
DECLARE #mode INT;
Set #mode = 1 --for Min set of records
--Set #mode = 100 --for Max / full set of records
SELECT TOP (#var) PERCENT * t.Column1 ,Count(t.Column2) AS Column2 FROM Table1 t
--Where some list of parameters
GROUP BY t.Column1 ,t.Column2

Can i have multiple select but only return one result set

If I have multiple selects like so:
select * from A where A.name = 'linköping'
IF ##ROWCOUNT = 0
begin
select * from A where A.amount = 45
end
...I get 1 result set if the first select returns stuff. But if it runs the second, I get two result sets; the first with no rows and the second with some rows.
Is there a way to only return the second result set if the second select is run ?
I write code like this because of Andrey Gordeev's answer to this post: Can you have if-then-else logic in SQL?
(MSSQL 2000)
Thanks!
You will need to prevent the first select by checking if you will get any results back before running the select.
For example:
IF EXISTS (SELECT 1 FROM A WHERE A.name = 'linköping')
BEGIN
SELECT * FROM A WHERE A.name = 'linköping'
END
ELSE
BEGIN
SELECT * FROM A WHERE A.amount = 45
END
No it is not possible The returning results are depending on number of select statements.
If you want to do the single select follow #RB or #Jwalin Shah solution.
This will work with IF-ELSE Logic. [Tested]
DECLARE #count as int
set #count = (SELECT count(1) from A where A.name = 'linköping')
if (#count = 0)
BEGIN
select * from A where A.amount = 45
END
ELSE
BEGIN
select * from A where A.name = 'linköping'
END
Try this
IF ##ROWCOUNT = 0
BEGIN
select * from A where A.amount = 45
END
ELSE
BEGIN
select * from A where A.name = 'linköping'
END