SELECT based on the result of another SELECT - sql

Is it possible to run another SELECT based on the result of the first SELECT?
For example:
SELECT COUNT(*) FROM table1
If the result is 0, I want to display the result of:
SELECT A, B, C FROM table2
If the result of the first SELECT is NOT 0, display the result of the first query and IGNORE the second.

You can certainly run a second select based on the results of the first:
You could do this:
declare #count integer = (select count(*) from table1)
if #count = 0
select ... from table1
else
select ... from table2

shouldn't need a variable for your problem
if EXISTS (select * from table1)
select A, B, C from table2

The result of the first query is the count, so you can use the variable to avoid re-running the query.
DECLARE #count int = ( SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS )
IF #count > 0
BEGIN
SELECT TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION FROM INFORMATION_SCHEMA.COLUMNS
END
ELSE
BEGIN
SELECT #count AS total
END

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 .

How to use case statement inside an SQL select Query

I need to get the output of a selected query depending on certain conditions
Means if(id=uid)
then I need the below query
select * from table1 where id=5;
else
I need the below one
select * from table1 where id=10
I know i can use if condition for this. But my query is very long one so when I use if else then it would look like
if(#id=#uid)
begin
select * from table1 where id=5;// query 1
end
else
select * from table1 where id=10;//query 2
but here I need to replace the entire query once again for a single check. I hope I can do something like this:
declare #id int=4;
declare #uid=10;
select * from table1 where
case
when #id=#uid
then
id=5
else
id=10;
end
Updation
I need one more condition too
in this case id=5 and uid=10
then if(id=uid)
then
select * from table1 where id=5
and
if(id!=uid)
then
select * from table1
something like this
You can use the case expression to return the value id should be equal to:
SELECT *
FROM table1
WHERE id = CASE WHEN #id = #uid THEN 5 ELSE 10 END;
EDIT:
The updated requirement in the question is to return all rows when #id != #uid. This can be done by comparing id to id:
SELECT *
FROM table1
WHERE id = CASE WHEN #id = #uid THEN 5 ELSE id END;
Alternatively, with this updated requirement, a simple or expression might be simpler to use:
SELECT *
FROM table1
WHERE #id = #uid OR id = 5;
SELECT * FROM table1
WHERE (id=5 AND #id=#uid) OR (id=10 AND #id<>#uid)
SELECT
*
FROM
table1
WHERE
(
#id = #uid
AND
id =5
)
OR
(
not #id = #uid
AND
id=10
)

Checking If Data in One Table Is Contained in Another

declare #q table (A int);
declare #a table (B int);
insert into #q select 1 union select 2 union select 3;
insert into #a select 0 union select 1 union select 2 union select 3 union select 4;
I want to know if the data of #q's column A is a subset of #a's column B.
This produces an error.
if (select A from #q) in (select B from #a)
print 'yes' else print 'no';
This works, but is it the best way of finding out?
if (select count(*) from #q) = (select count(*) from #q inner join #a on A = B)
print 'yes' else print 'no';
Or is there a better way?
Try using EXCEPT.
SELECT ColumnA
FROM TableA
EXCEPT
SELECT ColumnB
FROM TableB
It will give you a list of everything that's in A that's not in B.
You can insert the result from the above into a table variable, and then check its COUNT (0 = subset, anything else is not subset).
Try following. This basically looks for anything that is in #q but not in #a and gets its count. If the count is more than 0 then it returns No otherwise Yes.
SELECT CASE
WHEN COUNT(*) > 0 THEN 'No'
ELSE 'Yes'
END
FROM #q q
LEFT JOIN #a a
ON q.A = a.B
WHERE a.B iS NULL
Hope it helps.

T-Sql count string sequences over multiple rows

How can I find subsets of data over multiple rows in sql?
I want to count the number of occurrences of a string (or number) before another string is found and then count the number of times this string occurs before another one is found.
All these strings can be in random order.
This is what I want to achieve:
I have one table with one column (columnx) with data like this:
A
A
B
C
A
B
B
The result I want from the query should be like this:
2 A
1 B
1 C
1 A
2 B
Is this even possible in sql or would it be easier just to write a little C# app to do this?
Since, as per your comment, you can add a column that will unambiguously define the order in which the columnx values go, you can try the following query (provided the SQL product you are using supports CTEs and ranking functions):
WITH marked AS (
SELECT
columnx,
sortcolumn,
grp = ROW_NUMBER() OVER ( ORDER BY sortcolumn)
- ROW_NUMBER() OVER (PARTITION BY columnx ORDER BY sortcolumn)
FROM data
)
SELECT
columnx,
COUNT(*)
FROM marked
GROUP BY
columnx,
grp
ORDER BY
MIN(sortcolumn)
;
You can see the method in work on SQL Fiddle.
If sortcolumn is an auto-increment integer column that is guaranteed to have no gaps, you can replace the first ROW_NUMBER() expression with just sortcolumn. But, I guess, that cannot be guaranteed in general. Besides, you might indeed want to sort on a timestamp instead of an integer.
I dont think you can do it with a single select.
You can use AdventureWorks cursor:
create table my_Strings
(
my_string varchar(50)
)
insert into my_strings values('A'),('A'),('B'),('C'),('A'),('B'),('B') -- this method will only work on SQL Server 2008
--select my_String from my_strings
declare #temp_result table(
string varchar(50),
nr int)
declare #myString varchar(50)
declare #myLastString varchar(50)
declare #nr int
set #myLastString='A' --set this with the value of your FIRST string on the table
set #nr=0
DECLARE string_cursor CURSOR
FOR
SELECT my_string as aux_column FROM my_strings
OPEN string_cursor
FETCH NEXT FROM string_cursor into #myString
WHILE ##FETCH_STATUS = 0 BEGIN
if (#myString = #myLastString) begin
set #nr=#nr+1
set #myLastString=#myString
end else begin
insert into #temp_result values (#myLastString, #nr)
set #myLastString=#myString
set #nr=1
end
FETCH NEXT FROM string_cursor into #myString
END
insert into #temp_result values (#myLastString, #nr)
CLOSE string_cursor;
DEALLOCATE string_cursor;
select * from #temp_result
Result:
A 2
B 1
C 1
A 1
B 2
Try this :
;with sample as (
select 'A' as columnx
union all
select 'A'
union all
select 'B'
union all
select 'C'
union all
select 'A'
union all
select 'B'
union all
select 'B'
), data
as (
select columnx,
Row_Number() over(order by (select 0)) id
from sample
) , CTE as (
select * ,
Row_Number() over(order by (select 0)) rno from data
) , result as (
SELECT d.*
, ( SELECT MAX(ID)
FROM CTE c
WHERE NOT EXISTS (SELECT * FROM CTE
WHERE rno = c.rno-1 and columnx = c.columnx)
AND c.ID <= d.ID) AS g
FROM data d
)
SELECT columnx,
COUNT(1) cnt
FROM result
GROUP BY columnx,
g
Result :
columnx cnt
A 2
B 1
C 1
A 1
B 2

Store Procedure Select into a variable

How can I count the result of a table and pass into a Stored Procedure Variable?
DECLARE #totalrecs varchar
select count(id) from table1
I want the count record in the totalrecs variable.
like this
--will not count NULLS
select #totalrecs= count(id) from table1
--will count NULLS
select #totalrecs= count(*) from table1
DECLARE #totalCount Int
Select #totalCount = count(*)
From table1
Exec sp_DoSomething #Var = #totalCount
select #totalrecs= count(id) from table1