Stored Procedure Summation Of rows with same ID - sql-server

I have stored procedure in which I get Data In between the desired months from user.
Q1. I want to show Membername instead of memberID. How do i get member name here from the member master table?
Q2. Secondly I want to add these rows(summation). Like each row stores a int value. I want the same rows with same member ID to add up and show me one single row for each type.
for example if there are three entries for visitors in 3 months I dont want three separate rows display 1,1,1 instead I want a single row with value 3
USE [MTS]
GO
/****** Object: StoredProcedure [dbo].[sp_MTS_MemberTracking_generateReport] Script Date: 07-04-2015 14:48:52 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- sp_MTS_MemberTracking_generateReport '01/01/2015','03/01/2015'
-- =============================================
ALTER PROCEDURE [dbo].[sp_MTS_MemberTracking_generateReport]
-- Add the parameters for the stored procedure here
#monthYearFrom datetime , #monthYearTo datetime
AS
select MemberId,TrackingId,MonthYear, AttendanceInFormalMixer,AttendanceInFbb,GoodKarmaCredit,CupOfCofee,Business,Training,Visitors
from [dbo].[MTS_MemberTracking] MtsTracking
where MtsTracking.MonthYear >= #monthYearFrom and MtsTracking.MonthYear <= #monthYearTo

After looking through your code and web page. you need something like this.
ALTER PROCEDURE [dbo].[sp_MTS_MemberTracking_generateReport]
-- Add the parameters for the stored procedure here
#monthYearFrom datetime , #monthYearTo datetime
AS
select max(mtsmem.Name) Name,MtsTracking.MemberId,--TrackingId,MonthYear,
sum(Convert(int,AttendanceInFormalMixer))*10 AttendanceInFormalMixer,
sum(Convert(int,AttendanceInFbb))*10 AttendanceInFbb,
sum(CASE WHEN GoodKarmaCredit <> 0 THEN 10 ELSE 0 END) GoodKarmaCredit,
sum(CASE WHEN CupOfCofee <2 THEN CupOfCofee*5 ELSE 10 END) CupOfCofee,
sum(CASE WHEN Convert(int,Business)<>0 THEN 10 ELSE 0 END) Business,
sum(CASE WHEN Training<>0 THEN 10 ELSE 0 END) Training,
sum(CASE WHEN Visitors<>0 THEN 10 ELSE 0 END) Visitors,
convert(decimal(10,2),(sum(Convert(int,AttendanceInFormalMixer))*10 +
sum(Convert(int,AttendanceInFbb))*10 +
sum(CASE WHEN GoodKarmaCredit <> 0 THEN 10 ELSE 0 END) +
sum(CASE WHEN CupOfCofee <2 THEN CupOfCofee*5 ELSE 10 END) +
sum(CASE WHEN Convert(int,Business)<>0 THEN 10 ELSE 0 END) +
sum(CASE WHEN Training<>0 THEN 10 ELSE 0 END) +
sum(CASE WHEN Visitors<>0 THEN 10 ELSE 0 END) )*1.00/7)
UserScore
from [dbo].[MTS_MemberTracking] MtsTracking
inner join MTS_Members mtsmem on MtsTracking.MemberId = mtsmem.MemberId
where MtsTracking.MonthYear >= #monthYearFrom and MtsTracking.MonthYear <= #monthYearTo
group by MtsTracking.MemberId

Related

SQL Count entries with value per Date

I have a table in SQL Server:
CREATE TABLE healthRegistration
(
ID uniqueidentifier PRIMARY KEY,
RegisterDateTime DateTime NOT NULL,
RUFeelingWell Bool NOT NULL
);
The RegisterDateTime is the date and time that the user created the register and RUFeelingWell is a boolean value.
I want to create a query that returns 3 columns: Register Date, Count of entries with RUFeelingWell = False on that date, Count of entries with RUFeelingWell = True on that date
How can I do this?
SELECT CAST(T.RegisterDateTime AS DATE)REGISTERDATE,
SUM
(
CASE
WHEN T.RUFeelingWell =1 THEN 1
ELSE 0
END
)AS TRUE_RECORDS,
SUM
( CASE
WHEN T.RUFeelingWell =0 THEN 1
ELSE 0
END
)AS FALSE_RECORDS
FROM healthRegistration AS T
GROUP BY CAST(T.RegisterDateTime AS DATE)
Try this query:
Select
Convert(char(8), RegisterDateTime, 112),
Sum(Case RUFeelingWell When 1 Then 1 Else 0 End) As wellnos,
Sum(Case RUFeelingWell When 0 Then 1 Else 0 End) As notwellnos
From healthRegistration
Group By Convert(char(8), RegisterDateTime, 112)
Order By Convert(char(8), RegisterDateTime, 112)
Here Convert(char(8), RegisterDateTime, 112) gives date in YYYYMMDD format so that entries for a day are summed together.
Boolean values are stored as 1 and 0 in the database

SQL Server trigger - works on UPDATE but not on INSERT

The following trigger (which updates a column in the same table as the insert or update) works perfectly for UPDATEs, but doesn't seem to fire for INSERTs. Is it possible to run an update on?
What am I missing?
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[OnEvaluationCreateOrEdit]
ON [dbo].[tblEvaluationFormResultsSummary]
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
-- get the last id value of the record inserted or updated
DECLARE #id BIGINT;
SELECT #id = EvaluationFormResultSummaryID
FROM INSERTED;
-- Insert statements for trigger here
UPDATE A
SET A.Outcome = CASE
WHEN B.[# of fail alls] > 0 THEN 'Poor'
WHEN B.[# of Fail Amber] / [# of Live Questions] >= 0.3 THEN 'Poor'
WHEN B.[# of Fail Amber] > 0 THEN 'Development Needed'
WHEN B.[# of Fail Green] / [# of Live Questions] >= 0.4 THEN 'Development Needed'
WHEN B.[# of Fail Green] > 0 THEN 'Right First Time - Coaching Required'
ELSE 'Right First Time'
END
FROM
dbo.tblEvaluationFormResultsSummary AS A
INNER JOIN
(SELECT
SUM(CASE WHEN FormQuestionRatingOptionFailAll = 1 THEN 1 ELSE 0 END) as [# of fail alls],
SUM(CASE WHEN FormQuestionRatingOptionIsNA = 1 THEN 1 ELSE 0 END) as [# of N/A],
SUM(CASE WHEN FormQuestionRatingOptionLabel = 'Fail / Amber' THEN 1 ELSE 0 END) as [# of Fail Amber],
COUNT(EFRS.EvaluationFormResultsSummaryID) as [No of Questions],
COUNT(EFRS.EvaluationFormResultsSummaryID) - SUM(CASE WHEN FormQuestionRatingOptionIsNA = 1 THEN 1 ELSE 0 END) as [# of Live Questions],
SUM(CASE WHEN FormQuestionRatingOptionLabel = 'Fail / Green' THEN 1 ELSE 0 END) AS [# of Fail Green],
EFRS.EvaluationFormResultsSummaryID
FROM
dbo.tblEvaluationFormResultsDetails AS EFRS
INNER JOIN
dbo.tblEvaluationFormQuestionRatingOptions AS RO ON EFRS.QuestionRatingOptionID = RO.FormQuestionRatingOptionID
WHERE
(EFRS.EvaluationFormResultsSummaryID = #id)
GROUP BY
EFRS.EvaluationFormResultsSummaryID) B ON a.EvaluationFormResultSummaryID = B.EvaluationFormResultsSummaryID
WHERE
A.EvaluationFormResultSummaryID = #id
END
Thanks in advance!

Count the number of specific days of the month that have passed since a given date

I'm writing a function in SQL Server 2012 that will need to know the number of 3 specific days of the month that have passed since a given date. I can do this with a while loop, but its slow and I was looking for a better way.
Here is what I have so far:
Let's assume that GETDATE() = '11/14/2016' and #productDate = '10/1/2016'
--Get the number of "units" that have passed since the date on the label
DECLARE #unitCount INT = 0;
DECLARE #countingDate DATE
SET #countingDate = DATEADD(DAY,1,#productDate);--add 1 to prevent counting the date on the label as the first unit
WHILE (#countingDate < CAST(GETDATE() As date ))
BEGIN
SELECT #unitCount = #unitCount +
CASE
WHEN DAY(#countingDate) = 1 OR DAY(#countingDate) = 10 OR DAY(#countingDate) = 20 THEN 1
ELSE 0
END
SET #countingDate = DATEADD(DAY,1,#countingDate);
END
This will result in #unitCount = 4
GETDATE() of '11/20/2016' would result in #unitCount = 5
Without using a numbers table
create function dbo.fn_DateCounter
(
#datefrom date,
#dateto date
)
returns int
as
begin
return
-- number of complete months
3 *
(
(DATEPART(YYYY, #dateto) * 12 + DATEPART(MM, #dateto))
-(DATEPART(YYYY, #datefrom) * 12 + DATEPART(MM, #datefrom))
- 1
)
-- add on the extras from the first month
+ case when DATEPART(DD, #datefrom) < 10 then 2
when DATEPART(DD, #datefrom) < 20 then 1
else 0
end
-- add on the extras from the last month
+ case when DATEPART(DD, #dateto) > 20 then 3
when DATEPART(DD, #dateto) > 10 then 2
else 1
end
end
go
select dbo.fn_DateCounter('01-jan-2000','01-jan-2000') -- 0
select dbo.fn_DateCounter('01-jan-2000','10-jan-2000') -- 0
select dbo.fn_DateCounter('01-jan-2000','11-jan-2000') -- 1
select dbo.fn_DateCounter('01-jan-2000','20-jan-2000') -- 1
select dbo.fn_DateCounter('01-jan-2000','21-jan-2000') -- 2
select dbo.fn_DateCounter('11-jan-2000','21-jan-2000') -- 1
select dbo.fn_DateCounter('11-jan-2000','21-feb-2000') -- 4
select dbo.fn_DateCounter('01-jan-2000','01-jan-2001') -- 36
select dbo.fn_DateCounter('01-jan-2000','11-jan-2001') -- 37
You can use a combination of sum, case, and the dbo.spt_values table:
declare #productDate datetime = '11/01/2016',
#unitCount int
;with nums as ( -- use a CTE to build a number list
select top 1000 number from master..spt_values
)
select #unitCount = sum(
case when day(dateadd(day, n, #productDate)) in (1, 10, 20)
then 1 else 0 end
) -- add 1 for each 1,10,20 we find
from (
select n = row_number() over (order by nums.number)
from nums cross join nums as num -- 1000*1000 = 1 million rows
) n
where dateadd(day, n, #productDate) < getdate()
select #unitCount
This will grab each date between #productDate and getdate(). The case statement will select 1 for each 1/10/20, and 0 for every other date. Finally, we take the sum of the result.
For 11/1 - 11/11, it returns 1.
For 1/1 - 11/11, the result is 31.
EDIT: In the CTE (with nums as...), we select 1-1000, and then we do a cross join which gives us a million records to work with. The answer is still limited, but now you can go ~2700 years with this.

Stored procedure to check if less then one date entrance per week

I am working on a stored procedure. The input is going to be a date and ID and the procedure is going to set a value to true if there are 4 weeks with less then 2 inputs per week.
In my data only the weeks with the stars have less than two inputs and if I pass the date 7-7-2015 is going to set the output value to true
Any help will be appreciated. Do I need to iterate through every record and set a counter if less then two inputs or there is an easier way ?
ID Date
1 7-7-2015
2 6-23-2015
3 6-12-2015
1 7-8-2015
1 7-14-2015 *
1 7-21-2015 *
1 7-27-2015
1 7-28-2015
1 7-29-2015
1 7-30-2015
1 8-3-2015 *
1 8-11-2015 *
There might be better ways, but one way that should work is to use a windowed aggregate function (count) in a derived table, and then sum up the number of rows with count 1 and return true if the sum is >= 4. Something like this:
create proc sp_test (#id int, #d date)
as
select case when sum(c) >= 4 then 'true' else 'false' end status
from (
select c = count(*) over (partition by id, datepart(week, date))
from t -- this is your table
where id = #id and date >= #d
) a
where c = 1
go
Execute it using:
exec sp_test #id = 1, #d = '2015-07-07'

SQL Server - need assistance with sum and case statements

I'm using SQL Server 2005. I'm looking to add up the columns (AM, Midday, Evening) to see which ones contains the value "YES" and then take that total and multiply it by the rate for each row for a client.
Here is the query I have so far:
Select
Sum(Case When morning = 'yes' Then 1 Else 0 End) am_total,
Sum(Case When midday = 'yes' Then 1 Else 0 End) midday_total
From services
where client_id = 24
with the following output
am_total midday_total
45 49
When I introduce the rate variable, my query starts telling me I need the group_by clause and I don't think I'm ready for that since I still need to add the am_total and the midday_total together first and then multiply that by the rate.
Ultimately, all I'm looking for is the grand total.
If I understand your question, maybe this is what you need
declare #rate int
set #rate = 2 /*what ever rate is */
select am_total * #rate as am, midday_total * #rate as midday
from (
Select
Sum(Case When morning = 'yes' Then 1 Else 0 End) am_total,
Sum(Case When midday = 'yes' Then 1 Else 0 End) midday_total
From services
where client_id = 24
)
You can also join another table and use its columns in calculation
Select
Sum(Case When morning = 'yes' Then 1 * u.rate Else 0 End) am_total,
Sum(Case When midday = 'yes' Then 1 * u.rate Else 0 End) midday_total
From services srv inner join users u on services.id = u.service_id -- assuming this is relation
pay attention on u.rate above

Resources