Sql server Query : Conditional Select columns with top keyword - sql

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

Related

select COUNT and then condition 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 .

SQL Anywhere Error -824: Illegal reference to correlation name tableName

When I run this script on Sybase IQ:
declare #YEAR int=2017
declare #MON int=6
declare #DAY int=7
update MainTable
set MainTable.Amount=(X.Number+Y.Number),
MainTable.Total=(X.Total+Y.Total)
from (select 'Number'= count(*), 'Total'=case when SUM(T1_Total) is null then 0 else SUM(T1_Total) end
from Table1
where T1_Account_NO=MainTable.Account_NO
and T1_SENTRY_YEAR=#YEAR and T1_SENTRY_MON=#MON and T1_SENTRY_DAY=#DAY) X,
(select 'Number'= count(*), 'Total'=case when SUM(T2_TOTAL) is null then 0 else SUM(T2_TOTAL) end
from Table2 where T2_Account_NO = MainTable.Account_NO
and T2_YEAR=#YEAR and T2_MON=#MON and T2_DAY=#DAY )Y
where MainTable.YEAR=#YEAR
and MainTable.MON = #MON
and MainTable.DAY=#DAY
I got an error like this : " SQL Anywhere Error -824: Illegal reference to correlation name MainTable"
How can I surpass this problem?
Have you tried adding MainTable to the from clause, eg:
update Maintable
set ...
from MainTable,
(select ... )X,
(select ... )Y
where ...
NOTE: I work with Sybase ASE, which does not allow 'external' correlation names to be referenced within derived tables, so I'm wondering if SQLAnywhere has a similar limitation ... ?
What happens if you pull the MainTable joins out to the top-most level of the query, eg:
declare #YEAR int=2017
declare #MON int=6
declare #DAY int=7
update MainTable
set MainTable.Amount=(X.Number+Y.Number),
MainTable.Total=(X.Total+Y.Total)
from (select T1_account_NO, 'Number'= count(*), 'Total'=case when SUM(T1_Total) is null then 0 else SUM(T1_Total) end
from Table1
where T1_SENTRY_YEAR=#YEAR and T1_SENTRY_MON=#MON and T1_SENTRY_DAY=#DAY
group by T1_Account_NO) X,
(select T2_Account_NO, 'Number'= count(*), 'Total'=case when SUM(T2_TOTAL) is null then 0 else SUM(T2_TOTAL) end
from Table2 where T2_YEAR=#YEAR and T2_MON=#MON and T2_DAY=#DAY
group by T2_Account_NO)Y
where MainTable.YEAR=#YEAR
and MainTable.MON = #MON
and MainTable.DAY=#DAY
and MainTable.Account_NO = X.T1_Account_NO
and MainTable.Account_NO = Y.T2_Account_NO
One potential performance-related downside would be if the derived tables now generate a large set of records that won't be joined with MainTable (unless the SQLAnywhere query engine is able to flatten the query in some way ... ???).
If this is an issue of not allowing 'external' correlation names in derived tables, another (obvious ?) solution would be to create a couple #temp tables from the results of joining MainTable with Table1/Table2, then perform the update of MainTable as a join with the #temp tables. [Possibly indexing the #temp tables if the data volumes are large enough to justify, performance-wise, the indexes.]
Did you try adding MainTable to the FROM clause?
I surpass this problem like this:
declare #YEAR int=2017
declare #MON int=6
declare #DAY int=7
update MainTable
set MainTable.Amount= (X.Number),
MainTable.Total = (X.Total)
from (select T1_Account_NO,'Number'= count(*), 'Total'=case when SUM(T1_Total) is null then 0 else SUM(T1_Total) end
from Table1
where T1_SENTRY_YEAR=#YEAR and T1_SENTRY_MON=#MON and T1_SENTRY_DAY=#DAY
group by T1_Account_NO) X,
where X.T1_Account_NO=MainTable.Account_NO
and MainTable.YEAR=#YEAR
and MainTable.MON = #MON
and MainTable.DAY=#DAY
update MainTable
set MainTable.Amount= coalesce(MainTable.Amount,0)+(Y.Number),
MainTable.Total = coalesce(MainTable.Total,0)+(Y.Total)
(select T2_Account_NO,'Number'= count(*), 'Total'=case when SUM(T2_TOTAL) is null then 0 else SUM(T2_TOTAL) end
from Table2
where T2_YEAR=#YEAR and T2_MON=#MON and T2_DAY=#DAY
group by T2_Account_NO) Y
where MainTable.YEAR=#YEAR
and MainTable.MON = #MON
and MainTable.DAY=#DAY
and Y.T2_Account_NO = MainTable.Account_NO
I have seperated update script the two parts.

Statement blocks in SQL SELECT using IF ELSE

I'm trying to return different data depending on a variable in a SELECT. Something like this:
SELECT
IF #variable = 'YES'
column1, column2
ELSE
column3
FROM TABLE
What is this the proper way to use the IF condition in SQL? Or is there a better alternative to what I'm trying to accomplish?
If you want to return a different number of columns, you'll need to use an IF:
IF #variable = 'YES'
BEGIN
SELECT column1, column2
FROM YourTable
END
ELSE
BEGIN
SELECT column3
FROM YourTable
END
If you want different data on the same column (assuming the same datatype), you could use a CASE:
SELECT CASE WHEN #variable = 'YES' THEN column1 ELSE Column2 AS Data
FROM YourTable
You can use an IF statement, but you'll need to set up multiple queries. You can use a CASE for selecting one column or another, but not to select one or multiple like in your question.
DECLARE #var INT = 1;
DECLARE #test TABLE (
Col1 int,
Col2 int,
Col3 int
)
INSERT INTO #test VALUES (1,2,3)
IF #var = 1
BEGIN
SELECT Col1, Col2
FROM #test
END
ELSE
BEGIN
SELECT Col3
FROM #test
END

SQL Replace an empty SQL SELECT with word

I'm trying to solve the following problem:
I would like to make a select, when the result is empty it should be replaced with 'empty'
Else the result should be there.
That is my try:
select case (count*)
when 0 then 'empty'
ELSE
THEVALUEOFTHECOLUM
END AS RESULT
from Database.table where CarID = 12;
Thanks for every comment.
This should work, but you might have to convert the second occurrence of COUNT(*) to VARCHAR depending on the database used:
SELECT
CASE WHEN COUNT(*) = 0
THEN 'empty'
ELSE COUNT(*) -- CONVERT, TO_CHAR, ...
END AS result
FROM Database.table where CarID = 12;
SELECT
CASE
WHEN Q.countvalue = 0 THEN 'Empty'
ELSE CONVERT(NVARCHAR(10), Q.countvalue)
END AS RESULT
FROM
(
SELECT COUNT(*) AS countvalue
FROM Database.table WHERE CarID = 12
) AS Q
This feels hacky to me, but it will return the column data.
It is not one query, but it's still setwise.
declare #tmp table (id int)
declare #cnt int
insert into #tmp select col from table
select #cnt = count(*) from #tmp
if(#cnt = 0)
begin
select 'empty'
end
else
begin
select * from #tmp
end
Is it possible to code it with one query?
If there are no results -> no result found
else
Show all results, not only one
declare #tmp table (id int)
declare #cnt int
insert into #tmp select col from table
select #cnt = count(*) from #tmp
if(#cnt = 0)
begin
select 'empty'
end
else
begin
select * from #tmp
end

How do I check whether data is there or not in more than one sql table in one script?

I have more than 3 sql tables.
now i'm trying to select count(*) from all tables but how can i do this?.
I want to know whether data is present in all tables or not
I need to check the row count from previous business day ~15% for any table and it sends an email alert
I tried like following please help me to complete
PROCEDURE [dbo].[SendEmail_WSOTableDataAlert]
AS
BEGIN
declare #err int
IF NOT EXISTS (select 1 from T1) OR
NOT EXISTS (select 1 from T2)
BEGIN
set #error=1
END
//here i need to show which table is having empty data how can i do this please help
SET #tableHTML = #tableHTML + +
'</TABLE>' + #EmailFooter;
#error =1
then
send mail
END
Select
case when count(*) = 0 then
'No rows'
else
'Has rows'
end
FROM
(
Select * from #table1
UNION ALL
Select * from #table2
UNION ALL
Select * from #table3
) t
UPDATE
This makes sure all of then have at least one row and fail if any of them does not have record
Select
case when count(*) = 0 then
'No rows'
else
'Has rows'
end
FROM
(
Select top 1 1 found from #table1
intersect
Select top 1 1 found from #table2
intersect
Select top 1 1 found from #table3
) t
You can try multiplying the flags indicating zero counts together. If any of them is zero, the result will be zero.
select (case when (select count(*) from table1)=0 then 0 else 1 end
*case when (select count(*) from table2)=0 then 0 else 1 end
*case when (select count(*) from table3)=0 then 0 else 1 end) as no_zeros
If you would like to know which table has all zeros, you could transform the query as follows:
select (case when (select count(*) from table1)=0 then 1 else 0 end
+case when (select count(*) from table2)=0 then 2 else 0 end
+case when (select count(*) from table3)=0 then 4 else 0 end
+case when (select count(*) from table4)=0 then 8 else 0 end) as no_zeros
Use powers of two (1, 2, 4, 8, 16, 32, and so on) as your flags. Ones 1 in the binary representation of the result will tell you which tables have no records.
(select count() from table1 )
union all
(select count() from table2 )
union all
(select count(*) from table3 )
And then loop through the rows of the result
declare #count1 int
select #count1 = count(*)
from table1
declare #count2 int
select #count2 = count(*)
from table2
declare #count3 int
select #count3 = count(*)
from table3
if (#count1 + #count2 + #count3 = 0)
--do something
else
--do something else
You can use the EXISTS keyword to efficiently check if there is any data in a table.
IF NOT EXISTS (SELECT 1 FROM Table1) OR NOT EXISTS (SELECT 1 FROM Table2) OR NOT EXISTS (SELECT 1 FROM Table3)
BEGIN
/* do something */
END