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

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

Related

Performing a sub query alternatives

I'm looking for advice on how to get around the
"Cannot perform an aggregate function on an expression containing an
aggregate or a subquery".
On the Select PlateID From #Instances code, in the example below. Does anyone have any ideas or suggestions?
DECLARE #Instances AS TABLE(PlateID INT);
INSERT INTO #Instances(PlateID)VALUES(11638),(11637),(11632),(11659)
DECLARE #NumberofPlates INT;
SELECT #NumberofPlates = COUNT(*) FROM #Instances;
SELECT Instance_Plate_Room_Instance_ID_LNK
from dbo.M_Instance_Plate
WHERE Instance_Plate_Deleted = 0
group by Instance_Plate_Room_Instance_ID_LNK
having sum(case
when Instance_Plate_Plate_ID_LNK not in (SELECT PlateID
FROM #Instances)
then 1 else 0 end) = 0 and
SUM(case
when Instance_Plate_Plate_ID_LNK in (SELECT PlateID
FROM #Instances)
then 1 else 0 end) = #NumberofPlates;
In the absence of the structure of the physical table you included in your query I mocked up some random data for this, and put together a query that seems to work?
DECLARE #Instances AS TABLE(PlateID INT);
INSERT INTO #Instances(PlateID) VALUES (11638),(11637),(11632),(11632);
DECLARE #M_Instance_Plate TABLE (Instance_Plate_Plate_ID_LNK INT, Instance_Plate_Deleted INT, Instance_Plate_Room_Instance_ID_LNK INT);
INSERT INTO #M_Instance_Plate SELECT 11638, 0, 100;
INSERT INTO #M_Instance_Plate SELECT 11637, 0, 100;
INSERT INTO #M_Instance_Plate SELECT 11632, 0, 100;
INSERT INTO #M_Instance_Plate SELECT 11632, 0, 200;
INSERT INTO #M_Instance_Plate SELECT 11632, 1, 300;
DECLARE #NumberofPlates INT;
SELECT #NumberofPlates = COUNT(*) FROM #Instances;
WITH x AS (
SELECT
Instance_Plate_Room_Instance_ID_LNK,
SUM(CASE WHEN Instance_Plate_Plate_ID_LNK IS NULL THEN 1 ELSE 0 END) AS test_1, --Any missing
SUM(CASE WHEN Instance_Plate_Plate_ID_LNK IS NOT NULL THEN 1 ELSE 0 END) AS test_2 --Has coverage
FROM
#M_Instance_Plate ip
LEFT JOIN #Instances i ON i.PlateID = ip.Instance_Plate_Plate_ID_LNK
WHERE
Instance_Plate_Deleted = 0
GROUP BY
Instance_Plate_Room_Instance_ID_LNK)
SELECT
Instance_Plate_Room_Instance_ID_LNK
FROM
x
WHERE
test_1 = 0
AND test_2 = #NumberofPlates;
INSERT INTO #Instances(PlateID)VALUES(11638),(11637),(11632),(11659)
--DECLARE #NumberofPlates INT;
--SELECT #NumberofPlates = COUNT(*) FROM #Instances;
SELECT Instance_Plate_Room_Instance_ID_LNK
FROM dbo.M_Instance_Plate p
WHERE Instance_Plate_Deleted = 0
AND NOT EXISTS (
SELECT 1
FROM #Instances i
LEFT JOIN M_Instance_Plate m ON i.PlateID = m.Instance_Plate_Plate_ID_LNK
WHERE m.Instance_Plate_Room_Instance_ID_LNK = p.Instance_Plate_Room_Instance_ID_LNK
AND m.Instance_Plate_Plate_ID_LNK IS NULL
UNION ALL
SELECT 1
FROM #Instances i
JOIN M_Instance_Plate m ON i.PlateID = m.Instance_Plate_Plate_ID_LNK
WHERE m.Instance_Plate_Room_Instance_ID_LNK = p.Instance_Plate_Room_Instance_ID_LNK
GROUP BY i.PlateID
HAVING COUNT(*) != 1
)
Try this instead. Is equivalent expression (checks if plateId exists on your table variable and then matches with your variable #numberofplates)
HAVING #NumberofPlates = (
SELECT COUNT(1) AS cc
FROM #Instances AS a
WHERE a.PlateID = Instance_Plate_Plate_ID_LNK
)

Less expensive query?

I have a stored procedure that returns an integer 1 or 0 depending on specific criteria. It currently uses three select statements and it will be used heavily by multiple users across multiple locations. There has to be a more efficient way of doing this.
In short the query checks first to see if all checklist items on an order are completed (a separate table), then it checks to see if a field named BreakOutGuest (a bit field) is a 1 or 0. Depending on that result it checks to see if the total guest count is greater than 0 and the order total is zero. It returns the one or zero on all this criteria. Is there a more efficient way to do this? A temp table so I only have to hit the actual tables once? Below is the code.
#ORDERID INT
AS
BEGIN
DECLARE #AUTO_CLOSE INT
SET NOCOUNT ON;
--If all checklist items are marked complete move on, if not set #AUTO_CLOSE=0
IF NOT EXISTS(SELECT ORDERID FROM dbo.orderchecklistitems WHERE OrderID=#ORDERID AND CompletedON IS NULL)
BEGIN
--if BreakOutGuestFees is 1 only sum Guest_Count_1 + Guest_Count_2
IF EXISTS(SELECT * FROM dbo.Orders WHERE (GuestCount_1 + GuestCount_2)>1 AND OrderTotal=0 AND BreakoutGuestFees=1)
BEGIN
SET #AUTO_CLOSE=1
END
ELSE
SET #AUTO_CLOSE=0
--if BreakOutGuestFees is 0 only consider Guest_Count_1
IF EXISTS(SELECT * FROM dbo.Orders WHERE (GuestCount_1)>1 AND OrderTotal=0 AND BreakoutGuestFees=0)
BEGIN
SET #AUTO_CLOSE=1
END
ELSE
SET #AUTO_CLOSE=0
END
ELSE
SET #AUTO_CLOSE=0
END
If am not wrong you can combine two if clause into single if clause by using AND , OR logic. Try this.
IF NOT EXISTS(SELECT ORDERID
FROM dbo.orderchecklistitems
WHERE OrderID = #ORDERID
AND CompletedON IS NULL)
BEGIN
IF EXISTS(SELECT *
FROM dbo.Orders
WHERE ( ( GuestCount_1 + GuestCount_2 > 1
AND BreakoutGuestFees = 1 )
OR ( BreakoutGuestFees = 0
AND GuestCount_1 > 1 ) )
AND OrderTotal = 0
AND OrderID = #ORDERID)
SET #AUTO_CLOSE=1
ELSE
SET #AUTO_CLOSE=0
END
ELSE
SET #AUTO_CLOSE=0
You can perform your selection check with only one query
SELECT
(SELECT sum(1) FROM dual WHERE EXISTS (SELECT ORDERID FROM dbo.orderchecklistitems WHERE OrderID=#ORDERID AND CompletedON IS NULL)),
(SELECT sum(1) FROM dual WHERE EXISTS (SELECT 1 FROM dbo.Orders WHERE (GuestCount_1 + GuestCount_2)>1 AND OrderTotal=0 AND BreakoutGuestFees=1)),
(SELECT sum(1) FROM dual WHERE EXISTS (SELECT 1 FROM dbo.Orders WHERE (GuestCount_1)>1 AND OrderTotal=0 AND BreakoutGuestFees=0))
INTO
result1, result2, result3
from dual
then check results
DELCARE #AUTO_CLOSE INT = 0
IF NOT EXISTS(SELECT ORDERID
FROM dbo.orderchecklistitems
WHERE OrderID = #ORDERID
AND CompletedON IS NULL)
BEGIN
SET #AUTO_CLOSE =
(
SELECT
CASE
WHEN (GuestCount_1 + GuestCount_2 > 1) AND BreakoutGuestFees = 0 THEN 1
WHEN (GuestCount_1 > 1 ) AND BreakoutGuestFees = 1 THEN 1
ELSE 0 END
FROM dbo.orders
WHERE OrderTotal = 0 AND OrderID = #orderID
)
END

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.

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 to know if all the cells have the same value in some column

How to know if all the cells have the same value in some column (title changed)
I want to have a bit scalar value that tells me if all the values in a column equal something:
DECLARE #bit bit
SELECT #bit = TRUEFORALL(Name IS NOT NULL) FROM Contact
UPDATE
I now realized that I actually don't need the TrueForAll, what I do need is to make sure, that all values in a column are equal, for example, I want to know whether all Group.Items have the same price.
Why not?
select count( distinct price) from table
If returns 1, all values are the same... Add
where price is not null
if need be
For your updated requirement something like this would appear to do what you want:
DECLARE #IsSameGroup bit
SELECT #IsSameGroup = CASE WHEN COUNT(*) > 1 THEN 0 ELSE 1 END
FROM (SELECT Name FROM Contact GROUP BY Name) groups
When the count is greater the 1 you have two different names (or prices depending on what you group on)
Not very good for NULLs, but 2008 can do:
SELECT 1 WHERE 'Blue' = ALL ( SELECT Color FROM dbo.Hat )
OR
DECLARE #bit bit
SET #bit =
CASE ( SELECT 1 WHERE 'Blue' = ALL ( SELECT Color FROM dbo.Hat ))
WHEN 1 THEN 1 ELSE 0 END
UPDATE
All same color
SET #bit =
CASE(
SELECT 1 WHERE
(SELECT TOP(1) Color FROM dbo.Hat) = ALL ( SELECT Color FROM dbo.Hat )
)
WHEN 1 THEN 1 ELSE 0 END
Maybe this?
DECLARE #bit bit
if exists(SELECT Name FROM Contact WHERE Name IS NULL)
SET #bit = 0
ELSE
SET #bit = 1
This solves your first question:
SELECT
CASE
WHEN EXISTS(
SELECT 1
FROM Contact
WHERE Name IS NULL
) THEN 0
ELSE 1
END
ADDED:
This will solve your second:
SELECT
CASE
WHEN EXISTS(
SELECT TOP 1 1 FROM (
SELECT
ItemGroupName,
COUNT(Price) AS CNT
FROM ItemGroup
GROUP BY ItemGroupName
HAVING COUNT(Price) > 1
) t
) THEN 0
ELSE 1
END
By the way, when you use the exists function, its better to SELECT 1 (a constant) so less data gets returned