Combine multiple queries in 1 return row - sql

I have a query which should return 1 row for each DetectorID. What we currently have is the following:
DECLARE #StartDate datetime SET #StartDate = '2017-12-01 00:00'
DECLARE #EndDate datetime select #EndDate ='2018-01-01 00:00'
DECLARE #Limit1 real SET #Limit1 = 200; DECLARE #AssenLimit1 real SET #AssenLimit1 = 0;
DECLARE #Limit2 real SET #Limit2 = 300; DECLARE #AssenLimit2 real SET #AssenLimit2 = 0;
DECLARE #Limit3 real SET #Limit3 = 350; DECLARE #AssenLimit3 real SET #AssenLimit3 = 0;
DECLARE #Limit4 real SET #Limit4 = 400; DECLARE #AssenLimit4 real SET #AssenLimit4 = 0;
DECLARE #Limit5 real set #Limit5 = 500; DECLARE #AssenLimit5 real SET #AssenLimit5 = 0;
SELECT DetectorID, AVG(ValidWIM) AS 'PI_mean_WIM',
COUNT(ValidWIM) AS 'PI_mean_WIM2',
COUNT(CASE
WHEN ValidWIM > 0.5 THEN ValidWIM ELSE NULL END)
AS 'PI_mean_WIM3'
,AVG((ValidWDD_Left+ValidWDD_Right)/2) AS 'PI_mean_WDD'
,COUNT(ValidWDD_Left) AS 'PI_mean_WDD2'
,COUNT (CASE
WHEN (ValidWDD_Left>0.5 AND ValidWDD_Right>0.5) THEN ValidWDD_Left ELSE NULL END)
AS PI_mean_WDD3
,COUNT(CASE
WHEN AxleLoad IS NOT NULL Then TrainPassageInformationID ELSE NULL END)
AS 'nWheels'
, COUNT(CASE
WHEN (PeakForceLeft > #Limit1 OR PeakForceRight>#Limit1) THEN TrainPassageInformationID ELSE NULL END)
AS 'n>200'
, COUNT(CASE
WHEN (PeakForceLeft > #Limit2 OR PeakForceRight>#Limit2) THEN TrainPassageInformationID ELSE NULL END)
AS 'n>300'
, COUNT(CASE
WHEN (PeakForceLeft > #Limit3 OR PeakForceRight>#Limit3) THEN TrainPassageInformationID ELSE NULL END)
AS 'n>350'
, COUNT(CASE
WHEN (PeakForceLeft > #Limit4 OR PeakForceRight>#Limit4) THEN TrainPassageInformationID ELSE NULL END)
AS 'n>400'
, COUNT(CASE
WHEN (PeakForceLeft > #Limit5 OR PeakForceRight>#Limit5) THEN TrainPassageInformationID ELSE NULL END)
AS 'n>500'
From WheelDamage
where (TimeOfAxle > #StartDate AND TimeOfAxle < #EndDate) and DetectorID in (11,12)
GROUP BY DetectorID
order by DetectorID asc
SELECT DetectorID,
AVG(PeakForceLeft) AS 'NoiseLeft' FROM WheelDamage as t
where PeakForceLeft in (
select top 10 percent PeakForceLeft
from wheeldamage as tt
where tt.WheelDamageID = t.WheelDamageID AND tt.PeakForceLeft <> 0 AND tt.PeakForceLeft IS NOT NULL AND (t.TimeOfAxle > #StartDate AND t.TimeOfAxle < #EndDate)
order by tt.PeakForceLeft asc)
Group By DetectorID
order by DetectorID asc
SELECT DetectorID,
AVG(PeakForceRight) AS 'NoiseRight' FROM WheelDamage as t
where PeakForceLeft in (
select top 10 percent PeakForceRight
from wheeldamage as tt
where tt.WheelDamageID = t.WheelDamageID AND tt.PeakForceRight <> 0 AND tt.PeakForceLeft IS NOT NULL AND (t.TimeOfAxle > #StartDate AND t.TimeOfAxle < #EndDate)
order by tt.PeakForceLeft asc)
Group By DetectorID
order by DetectorID asc
SELECT DetectorId, COUNT (DateTime) AS 'Tags1'
FROM [TagPassage]
WHERE Valid = 1 AND (DateTime > #StartDate AND DateTime < #EndDate)
GROUP by DetectorID
Order by DetectorID asc
SELECT DetectorID, COUNT(CASE
WHEN (TotalWeight=0 OR TotalWeight IS NULL) AND (HasTrainStandStill<>1 OR HasTrainStandStill IS NULL) THEN (TrainPassageInformationID) ELSE NULL END) AS 'notAnalyzed'
, SUM (TotalWeight) AS 'TotalWeight'
FROM TrainPassageInformation
WHERE (Datetime > #StartDate AND Datetime < #EndDate)
Group By DetectorID
order by DetectorID asc
This is returing 5 new rows which I understand. This is because i have 5 select statements. However, I need to know how i can put the bottom 4 select statements in the top one so that it will only return 1 row.
I have tried with Select(Select X xxx). But that gave the error that it is returning more then 1 rows.
The image above is showing the current result. I want the bottom 4 tables to be columns in the first table.

can you just join/left join all the scripts together as table and link by DetectorID, then u can select the columns from the 4 scripts at the bottom to the right.

Related

Query with Join of tables is taking long time to execute 5 min

SELECT
B.AccountBranchID
,B.VoucherNo
,B.BranchName AS BranchName
,B.InvoiceNo
,CONVERT(VARCHAR, B.InvoiceDate, 103) AS InvoiceDate
,CONVERT(VARCHAR, B.VoucherDate, 103) AS VoucherDate
,B.CustomerName
,B.RefID
,LN.AccountName AS LedgerName
,b.SalesPersonName AS SalesPersonName
,LN.LedgerCode
,B.AgentName
,B.ShipperName
,B.Segment
,B.TransactionType
,B.JobNo
,CONVERT(VARCHAR, B.JOBDate, 103) AS JOBDate
,B.MAWBNo
,B.HAWBNo
,B.AccountName
,B.LedgerCode AS AccountLedgerCode
,B.CurrencyCode
,ISNULL(B.Amount, 0) AS Amount
,B.ChargeExRate
,(CASE B.CRDR
WHEN 'CR' THEN (B.ChargeBaseAmount * -1)
ELSE B.ChargeBaseAmount
END) AS ChargeBaseAmount
,(CASE B.CRDR
WHEN 'CR' THEN 'Credit'
ELSE 'Debit'
END) AS CRDR
FROM VW_VoucherTR AS B
INNER JOIN VW_VoucherTR AS LN
ON B.VoucherID = LN.VoucherID
WHERE B.CompanyID = #CompanyID
AND (CASE #Type
WHEN 'I' THEN B.InvoiceDate
ELSE B.VoucherDate
END) BETWEEN ISNULL(#FromDate, (SELECT
FYearStart
FROM Secmst_FinancialYear
WHERE FyearId = #yearID)
) AND ISNULL(#ToDate, GETDATE())
AND (#Segment IS NULL
OR B.Segment = #Segment)
AND (#BranchMappingID IS NULL
OR B.BranchMappingID = #BranchMappingID)
AND B.VoucherTypeCode IN ('sv')
AND B.IsDeleted = 0
AND (B.GroupName <> 'Sundry Creditors'
AND B.GroupName <> 'Sundry Debtors')
AND LN.GroupName IN ('Sundry Debtors', 'Sundry Creditors')
The subquery in the BETWEEN is probably what is killing you. Have you looked at the execution plan?
BETWEEN ISNULL(#FromDate, (
SELECT FYearStart
FROM Secmst_FinancialYear
WHERE FyearId = #yearID
))
AND ISNULL(#ToDate, GETDATE())
What's happening is you are running that query across every row, and by my looks, that's unnecessary because you are only needing static dates there (not anything based on the joined rows.)
Try this:
DECLARE #FromDateActual datetime = ISNULL(#FromDate, (
SELECT FYearStart
FROM Secmst_FinancialYear
WHERE FyearId = #yearID
));
DECLARE #ToDateActual datetime = ISNULL(#ToDate, GETDATE());
SELECT B.AccountBranchID
,B.VoucherNo
,B.BranchName AS BranchName
,B.InvoiceNo
,convert(VARCHAR, B.InvoiceDate, 103) AS InvoiceDate
,convert(VARCHAR, B.VoucherDate, 103) AS VoucherDate
,B.CustomerName
,B.RefID
,LN.AccountName AS LedgerName
,b.SalesPersonName AS SalesPersonName
,LN.LedgerCode
,B.AgentName
,B.ShipperName
,B.Segment
,B.TransactionType
,B.JobNo
,convert(VARCHAR, B.JOBDate, 103) AS JOBDate
,B.MAWBNo
,B.HAWBNo
,B.AccountName
,B.LedgerCode AS AccountLedgerCode
,B.CurrencyCode
,ISNULL(B.Amount, 0) AS Amount
,B.ChargeExRate
,(
CASE B.CRDR
WHEN 'CR'
THEN (B.ChargeBaseAmount * - 1)
ELSE B.ChargeBaseAmount
END
) AS ChargeBaseAmount
,(
CASE B.CRDR
WHEN 'CR'
THEN 'Credit'
ELSE 'Debit'
END
) AS CRDR
FROM VW_VoucherTR AS B
INNER JOIN VW_VoucherTR AS LN ON B.VoucherID = LN.VoucherID
WHERE B.CompanyID = #CompanyID
AND (
CASE #Type
WHEN 'I'
THEN B.InvoiceDate
ELSE B.VoucherDate
END
) BETWEEN #FromDateActual
AND #ToDateActual
AND (
#Segment IS NULL
OR B.Segment = #Segment
)
AND (
#BranchMappingID IS NULL
OR B.BranchMappingID = #BranchMappingID
)
AND B.VoucherTypeCode IN ('sv')
AND B.IsDeleted = 0
AND (
B.GroupName <> 'Sundry Creditors'
AND B.GroupName <> 'Sundry Debtors'
)
AND LN.GroupName IN (
'Sundry Debtors'
,'Sundry Creditors'
)
Beyond that you could consider adding non-clustered indexes. The Query Analyzer may even suggest a couple. But you'll want to be careful there, depending on how the data is used and loaded, as too many indexes or large ones can lead to further performance issues in other places (row insertions, page fragmentation, etc).
There could be many reasons for it, but one thing is quite plain. The following part is not sargable.
(CASE #Type
WHEN 'I' THEN B.InvoiceDate
ELSE B.VoucherDate
END) BETWEEN ISNULL(#FromDate, (SELECT
FYearStart
FROM Secmst_FinancialYear
WHERE FyearId = #yearID)
) AND ISNULL(#ToDate, GETDATE())
Should be rewritten to be sargable, so that indexes can be used.
SELECT #FromDate = ISNULL(#FromDate, (SELECT
TOP 1 FYearStart
FROM Secmst_FinancialYear
WHERE FyearId = #yearID)) )
SELECT #ToDate = ISNULL(#ToDate, GETDATE())
SELECT
...
WHERE
...
AND
((#Type='I' AND B.InvoiceDate BETWEEN #FromDate AND #ToDate)
OR
(#Type<>'I' AND B.VoucherDate BETWEEN #FromDate AND #ToDate))
AND
...
Of course proper indexing is the way how to speed up your query, if no indexes are on InvoiceDate, VoucherDate, etc. then your query will use full table scan instead of index seek and it will be slow.

Conditional Where when using Group By

I have a working procedure to show the report for given range of period.
The below proc finds all the bookings for the given period of time and shows for each month group
CREATE PROCEDURE [dbo].[GetSummaryOverviewReport] (
#StartDate SMALLDATETIME = NULL
,#EndDate SMALLDATETIME = NULL
,#IncludeVAT BIT = 0
,#AddedAfter SMALLDATETIME
,#HasObservation BIT = 0
,#IncludeCancelledBooking BIT = 0
)
AS
BEGIN
SET NOCOUNT ON
BEGIN
SELECT YEAR(StartTime) [Year]
,MONTH(StartTime) [Month]
,COUNT(BookingId) [BookingCount]
,SUM(CASE
WHEN IsVAT = 1
AND #IncludeVAT = 1
THEN (Price / 100) * 80
ELSE Price
END) AS TotalPrice
,PaidCount = sum(CASE
WHEN B.PaymentStatus = 'FullyPaid'
THEN 1
ELSE 0
END)
,PaidSum = sum(CASE
WHEN B.PaymentStatus = 'FullyPaid'
THEN (
CASE
WHEN IsVAT = 1
AND #IncludeVAT = 1
THEN (Price / 100) * 80
ELSE Price
END
)
ELSE 0
END)
,C.CategoryId
,CategoryName
FROM Category c
LEFT JOIN Booking B ON C.CategoryId = B.CategoryId
WHERE B.AddedDateTime > #AddedAfter
AND ISNULL(B.IsCancelled, 0) = 0
AND (
(
B.StartTime BETWEEN #StartDate
AND #EndDate
)
OR (
B.StartTime BETWEEN #StartDate
AND #EndDate
)
)
AND (
#HasObservation = 0
OR B.PatientID IN (
SELECT PatientID
FROM PatientXObservation O
WHERE ObservationId IN (
1
,2
,4
)
)
)
GROUP BY YEAR(StartTime)
,MONTH(StartTime)
,C.CategoryId
,CategoryName
ORDER BY 1
,2
,CategoryName
END
END
Now we want to add a filter #IncludeCancelledBooking parameter. So user can select whether to show cancelled bookings or not. As of now the procedure ignores the cancelled booking and shows only non cancelled booking..
I couldn't able to find out how to add this condition while grouping the records. I need to use AND ISNULL(B.IsCancelled, 0) = 0 based on #IncludeCancelledBooking
Is this the logic that you want?
(#IncludeCancelled <> 'Y' OR Booking ISNULL(B.IsCancelled, 0) = 0)
If IsCancelled is also a BIT(like #IncludeCancelled), then you could use:
AND ISNULL(B.IsCancelled, 0) IN (0, #IncludeCancelled)
If #IncludeCancelled is 0, then this is effectively the same logic you have now (i.e. = 0). If #IncludeCancelled is 1, then this includes where IsCancelled = 1.
Assuming you are passing value 1 for the variable #IncludeCancelled for including the cancelled booking. Then change the WHERE condition like below.
AND ISNULL(B.IsCancelled,0)=
CASE WHEN #IncludeCancelled=1
THEN ISNULL(B.IsCancelled,0)
ELSE 0 END

MAX Date of multiple columns?

How do you return 1 value per row of the max of several columns:
TableName [RefNumber, FirstVisitedDate, SecondVisitedDate, RecoveryDate, ActionDate]
I want MaxDate of (FirstVisitedDate, SecondVisitedDate, RecoveryDate, ActionDate) these dates for all rows in single column and I want another new column(Acion) depends on Max date column for ex: if Max date is from FirstVisitedDate then it will be 'FirstVisited' or if Max date is from SecondVisitedDate then it will be 'SecondVisited'...
The Total result Like:
Select RefNumber, Maxdate, Action From Table
group by RefNumber
The brute force approach isn't so bad with four columns:
select (case when FirstVisitedDate >= SecondVisitedDate and
FirstVisitedDate >= RecoveryDate and
FirstVisitedDate >= ActionDate
then FirstVisitedDate
when SecondVisitedDate >= RecoveryDate and
SecondVisitedDate >= ActionDate
then SecondVisitedDate
when RecoveryDate >= ActionDate
then RecoveryDate
else ActionDate
end),
(case when FirstVisitedDate >= SecondVisitedDate and
FirstVisitedDate >= RecoveryDate and
FirstVisitedDate >= ActionDate
then 'FirstVisitedDate'
when SecondVisitedDate >= RecoveryDate and
SecondVisitedDate >= ActionDate
then 'SecondVisitedDate'
when RecoveryDate >= ActionDate
then 'RecoveryDate'
else 'ActionDate'
end)
from table t;
EDIT:
Doing this in a group by is just a question of adding aggregation functions:
select RefNumber,
(case when max(FirstVisitedDate) >= max(SecondVisitedDate) and
max(FirstVisitedDate) >= max(RecoveryDate) and
max(FirstVisitedDate) >= max(ActionDate)
then max(FirstVisitedDate
when max(SecondVisitedDate) >= max(RecoveryDate) and
max(SecondVisitedDate) >= max(ActionDate)
then max(SecondVisitedDate)
when max(RecoveryDate) >= max(ActionDate)
then max(RecoveryDate)
else max(ActionDate)
end),
(case when max(FirstVisitedDate) >= max(SecondVisitedDate) and
max(FirstVisitedDate) >= max(RecoveryDate) and
max(FirstVisitedDate) >= max(ActionDate)
then 'FirstVisitedDate'
when max(SecondVisitedDate) >= max(RecoveryDate) and
max(SecondVisitedDate) >= max(ActionDate)
then 'SecondVisitedDate'
when max(RecoveryDate) >= max(ActionDate)
then 'RecoveryDate'
else 'ActionDate'
end)
from table t
group by RefNumber;
;WITH cte AS (
-- Build table of date
SELECT [RefNumber],
[ActionDate]= [FirstVisitedDate],
[Action] = 'First Visited'
FROM [Table1]
UNION ALL
SELECT [RefNumber],
[SecondVisitedDate],
'Second Visited'
FROM [Table1]
UNION ALL
SELECT [RefNumber],
[RecoveryDate],
'Recover'
FROM [Table1]
), cte2 AS (
-- Add row_number to pull most recent to top
SELECT [RefNumber],
[Action],
[ActionDate],
[DateRank] =
ROW_NUMBER() OVER (PARTITION BY RefNumber
ORDER BY [ActionDate] DESC)
FROM [cte]
)
-- select only the most recent
SELECT *
FROM cte2
WHERE [DateRank] = 1
SELECT RecordID, MaxDate
FROM SourceTable
CROSS APPLY (SELECT MAX(d) MaxDate
FROM (VALUES (date1), (date2), (date3),
(date4), (date5), (date6),
(date7)) AS dates(d)) md
I wrote a custom function to do this:
CREATE FUNCTION [dbo].[MaxOf5]
(
#D1 DateTime,
#D2 DateTime,
#D3 DateTime,
#D4 DateTime,
#D5 DateTime
)
RETURNS DateTime
AS
BEGIN
DECLARE #Result DateTime
SET #Result = COALESCE(#D1, #D2, #D3, #D4, #D5)
IF #D2 IS NOT NULL AND #D2 > #Result SET #Result = #D2
IF #D3 IS NOT NULL AND #D3 > #Result SET #Result = #D3
IF #D4 IS NOT NULL AND #D4 > #Result SET #Result = #D4
IF #D5 IS NOT NULL AND #D5 > #Result SET #Result = #D5
RETURN #Result
END
To call this, and calculated your Action column, this should work:
SELECT
MaxDate,
CASE WHEN MaxDate = FirstVisitedDate THEN 'FirstVisited'
WHEN MaxDate = SecondVisitedDate THEN 'SecondVisited'
WHEN MaxDate = RecoveryDate THEN 'Recovery'
WHEN MaxDate = ActionDate THEN 'Action'
END AS [Action]
FROM (
SELECT
RefNumber,
dbo.MaxOf5(FirstVisitedDate, SecondVisitedDate, RecoveryDate, ActionDate) AS MaxDate,
FirstVisitedDate, SecondVisitedDate, RecoveryDate, ActionDate
FROM table
) AS data
Note that is is possible for more than one of your dates to be tied for the max date. In this case, the order of your WHEN clauses determines which one wins.

Check result of transaction before updating table

I have the following stored procedure:
CREATE PROCEDURE [dbo].[vRpt_VolunteerPaymentsAll]
#startdate DATETIME = NULL ,
#enddate DATETIME = NULL ,
#user NVARCHAR(50)
AS /* This procedure generates Team Events that have been audtied */
DECLARE #sd DATETIME
DECLARE #ed DATETIME
/* Ensure that the start and end dates covert whole days */
SET #sd = CONVERT(VARCHAR(10), #startdate, 120) + ' 00:00:00'
SET #ed = CONVERT(VARCHAR(10), #enddate, 120) + ' 23:59:59'
DECLARE #id INT
INSERT INTO vVolunteerPaymentEvents
( StartDate ,
EndDate ,
Verifier ,
DatePaid ,
RecordsPaid ,
UnDone ,
Comments ,
Flags
)
VALUES ( #startdate ,
#enddate ,
/*Get the users initials*/
( SELECT dbo.vUsers.Initials
FROM dbo.vUsers
WHERE dbo.vUsers.UserID = #user
) ,
GETDATE() ,
/* Count how many records are going ot be affected*/
( SELECT COUNT(*)
FROM dbo.vVolunteerPayments
WHERE dbo.vVolunteerPayments.PaymentEventID = 0
AND ( dbo.vVolunteerPayments.DateCreated BETWEEN #sd
AND
#ed )
) ,
0 ,
'' ,
0
)
/*Set the id of the payment event id for the volunteer payments*/
SET #id = SCOPE_IDENTITY() ;
--get the totals for the payment based on the
--#id value just inserted above
UPDATE dbo.vVolunteerPayments
SET dbo.vVolunteerPayments.PaymentEventID = #id ,
dbo.vVolunteerPayments.DatePaid = GETDATE()
WHERE dbo.vVolunteerPayments.PaymentEventID = 0
AND dbo.vVolunteerPayments.DateCreated BETWEEN #sd
AND #ed
SELECT * FROM
(SELECT VOLSACCT.volunteerid ,
ISNULL(VOLS.Forename, '') + ' ' + ISNULL(VOLS.Surname, '') AS Name ,
VOLSACCT.SortCode ,
VOLSACCT.AccountName ,
VOLSACCT.AccountNumber ,
SUM(CASE [Type]
WHEN 1001
THEN CASE WHEN PMTS.DateCreated BETWEEN #sd AND #ed
--AND PMTS.PaymentEventID = 0
--AND PMTS.VolunteerId = #volunteerid
THEN Amount
END
ELSE 0
END) AS Reimbursements ,
SUM(CASE [Type]
WHEN 1002
THEN CASE WHEN PMTS.DateCreated BETWEEN #sd AND #ed
--AND PMTS.PaymentEventID = 0
--AND PMTS.VolunteerId = #volunteerid
THEN Amount
END
ELSE 0
END) AS MobilePhoneCharges ,
SUM(CASE [Type]
WHEN 1003
THEN CASE WHEN PMTS.DateCreated BETWEEN #sd AND #ed
--AND PMTS.PaymentEventID = 0
--AND PMTS.VolunteerId = #volunteerid
THEN Amount
END
ELSE 0
END) AS GPContributions ,
SUM(CASE [Type]
WHEN 12
THEN CASE WHEN PMTS.DateCreated BETWEEN #sd AND #ed
--AND PMTS.PaymentEventID = 0
--AND PMTS.VolunteerId = #volunteerid
THEN Amount
END
ELSE 0
END) AS GPExpenses ,
SUM(CASE [Type]
WHEN 137
THEN CASE WHEN PMTS.DateCreated BETWEEN #sd AND #ed
--PaymentEventID = 0
--AND PMTS.VolunteerId = #volunteerid
THEN Amount
END
ELSE 0
END) AS Expenses ,
SUM(CASE WHEN PMTS.DateCreated BETWEEN #sd AND #ed
--AND PMTS.PaymentEventID = 0
--AND PMTS.VolunteerId = #volunteerid
THEN Mileage
ELSE 0
END) AS TotalMileageWeek ,
VOLSACCT.BACS,
PMTS.ChargeRate
FROM dbo.vVolunteerPayments PMTS
INNER JOIN dbo.vVolunteerAccounts VOLSACCT ON PMTS.VolunteerId = VOLSACCT.VolunteerID
INNER JOIN dbo.vVolunteers VOLS ON PMTS.VolunteerId = VOLS.VolunteerID
WHERE PMTS.PaymentEventID = #id
GROUP BY VOLSACCT.volunteerid ,
VOLSACCT.AccountName ,
VOLSACCT.AccountNumber ,
VOLSACCT.BACS ,
VOLSACCT.SortCode ,
VOLS.Forename ,
VOLS.Surname,
PMTS.ChargeRate) AS A
WHERE
GPContributions >0
OR GPExpenses > 0
OR MobilePhoneCharges > 0
OR Expenses > 0
OR Reimbursements > 0
OR Expenses > 0
OR TotalMileageWeek >0
ORDER BY Name
It basically inserts a summary record of affected transactions into one table (volunteerpaymentevent) , updates existing records of another table (volunteerpayments(datepaid and payment event id)) and then returns record sets of sumary values within a join
However I have found that if the join fails or there are no joins at all (and consequently nothing outputs) then the update part of the procedure still updates the records
Is there a way of checking the result of the inner join before updating the records in the volunteerpayments table
Cheers
You need to put your code inside a transaction:
ALTER PROCEDURE [dbo].[vRpt_VolunteerPaymentsAll]
#startdate DATETIME = NULL ,
#enddate DATETIME = NULL ,
#user NVARCHAR(50)
AS
begin transaction
your procedure code
commit transaction
See MSDN for more on transactions.

Combining SQL Server Queries

I am using SQL Server and I have two tables and I would like to combine into one query that I can use to fill a gridview.
Table1 dbo.Work
UID (PK, int)
Tech_Ticket (int)
RMA_Ticket (int)
Region (nchar10)
Completed (nchar10)
FA (nchar10)
Agent (nvarchar50)
Tracking (nvarchar50)
Date_Added (date)
Date_Updated (date)
Table2 dbo.Orders
UID (PK, int)
Order (int)
Agent (nvarchar50)
Ticket (int)
Notes (nvarchar50)
Right now I have them setup as two separate queries and two separate tables.
Query1:
SELECT [Agent],
SUM(CASE WHEN [Date_Added] BETWEEN #startDate AND #endDate THEN 1 ELSE 0 END) AS 'New ',
SUM(CASE WHEN [Date_Updated] BETWEEN #startDate AND #endDate THEN 1 ELSE 0 END) AS 'Worked',
SUM(CASE WHEN [Completed] = 'yes' AND [Date_Updated] BETWEEN #startDate AND #endDate THEN 1 ELSE 0 END) AS 'Completed',
SUM(CASE WHEN [Failure_Analysis] = 'yes' AND [Date_Updated] BETWEEN #startDate AND #endDate THEN 1 ELSE 0 END) AS 'FA'
FROM Work
GROUP BY [Agent]
Query2:
SELECT [Agent]
SUM(CASE WHEN [Date] BETWEEN #startDate AND #endDate THEN 1 ELSE 0 END) AS 'Orders'
FROM Orders
GROUP BY [Agent]
Is there a way to combine these two queries into one?
You can JOIN them. Assuming that Work is the main table, it should be like this:
SELECT A.*, B.Orders
FROM ( SELECT [Agent],
SUM(CASE WHEN [Date_Added] BETWEEN #startDate AND #endDate THEN 1 ELSE 0 END) AS 'New',
SUM(CASE WHEN [Date_Updated] BETWEEN #startDate AND #endDate THEN 1 ELSE 0 END) AS 'Worked',
SUM(CASE WHEN [Completed] = 'yes' AND [Date_Updated] BETWEEN #startDate AND #endDate THEN 1 ELSE 0 END) AS 'Completed',
SUM(CASE WHEN [Failure_Analysis] = 'yes' AND [Date_Updated] BETWEEN #startDate AND #endDate THEN 1 ELSE 0 END) AS 'FA'
FROM Work
GROUP BY [Agent]) A
LEFT JOIN (SELECT [Agent]
SUM(CASE WHEN [Date] BETWEEN #startDate AND #endDate THEN 1 ELSE 0 END) AS 'Orders'
FROM Orders
GROUP BY [Agent]) B
ON A.[Agent] = B.[Agent]