ETFairfax
asked on
Sql Calculation
CREATE TABLE [dbo].[Task]
(
[id] [int] IDENTITY(1,1) NOT NULL,
[name] [nvarchar](50) NOT NULL,
[completetionStatus] [nvarchar](10) NOT NULL,
CONSTRAINT [PK_Task] PRIMARY KEY CLUSTERED ([id] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[SubTask]
(
[id] [int] IDENTITY(1,1) NOT NULL,
[taskId] [int] NOT NULL,
[subTaskCompletionStatus] [int] NOT NULL,
CONSTRAINT [PK_SubTask] PRIMARY KEY CLUSTERED ([id] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
ON [PRIMARY]
ALTER TABLE [dbo].[SubTask] WITH CHECK ADD CONSTRAINT [FK_SubTask_Task] FOREIGN KEY([taskId])
REFERENCES [dbo].[Task] ([id])
ALTER TABLE [dbo].[SubTask] CHECK CONSTRAINT [FK_SubTask_Task]
INSERT INTO [Task] ([name], [completetionStatus]) VALUES ('Task 01', 'S');
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (1, 0);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (1, 0);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (1, 0);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (1, 0);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (1, 0);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (1, 0);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (1, 0);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (1, 0);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (1, 0);
INSERT INTO [Task] ([name], [completetionStatus]) VALUES ('Task 02', 'S');
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (2, 0);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (2, 0);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (2, 0);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (2, 0);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (2, 0);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (2, 0);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (2, 0);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (2, 0);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (2, 0);
Given the tables and data above (a simplified version of what actually exists), I need a stored procedure which, when passed a task Id, will update the [completetionStatus] of the [Task] table, with a value calculated from the values stored in the [SubTask] table.
Psuedo code for the calculation...
if (100% of subTaskCompletionStatus = 2)
{
set Task table completetionStatus to 'CO'
}
else if (100% of subTaskCompletionStatus = 3)
{
set Task table completetionStatus to 'CL'
}
else if (100% of subTaskCompletionStatus = 2 AND 3)
{
set Task table completetionStatus to 'CL'
}
else if (>0% but <100% of subTaskCompletionStatus = 2 or 3)
{
set Task table completetionStatus to 'PC'
}
else if(100% of subTaskCompletionStatus >= 4)
{
set Task table completetionStatus to 'F'
}
Ultimatly I need a solution for SQL Server 2005, but it would be great if a solution for SQL 2000 could also be provided. I would also like to avoid the use of triggers.
This needs to be as slick as possible as it will be a routine being hit on a very regular basis. Any solutions I come up with are either to "clunky" or I am not sure how to implement.
Let me know if you are unsure of what I am going on about!!
Many thanks for any help given.
(
[id] [int] IDENTITY(1,1) NOT NULL,
[name] [nvarchar](50) NOT NULL,
[completetionStatus] [nvarchar](10) NOT NULL,
CONSTRAINT [PK_Task] PRIMARY KEY CLUSTERED ([id] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[SubTask]
(
[id] [int] IDENTITY(1,1) NOT NULL,
[taskId] [int] NOT NULL,
[subTaskCompletionStatus] [int] NOT NULL,
CONSTRAINT [PK_SubTask] PRIMARY KEY CLUSTERED ([id] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
ON [PRIMARY]
ALTER TABLE [dbo].[SubTask] WITH CHECK ADD CONSTRAINT [FK_SubTask_Task] FOREIGN KEY([taskId])
REFERENCES [dbo].[Task] ([id])
ALTER TABLE [dbo].[SubTask] CHECK CONSTRAINT [FK_SubTask_Task]
INSERT INTO [Task] ([name], [completetionStatus]) VALUES ('Task 01', 'S');
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus])
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus])
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus])
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus])
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus])
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus])
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus])
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus])
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus])
INSERT INTO [Task] ([name], [completetionStatus]) VALUES ('Task 02', 'S');
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus])
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus])
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus])
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus])
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus])
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus])
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus])
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus])
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus])
Given the tables and data above (a simplified version of what actually exists), I need a stored procedure which, when passed a task Id, will update the [completetionStatus] of the [Task] table, with a value calculated from the values stored in the [SubTask] table.
Psuedo code for the calculation...
if (100% of subTaskCompletionStatus = 2)
{
set Task table completetionStatus to 'CO'
}
else if (100% of subTaskCompletionStatus = 3)
{
set Task table completetionStatus to 'CL'
}
else if (100% of subTaskCompletionStatus = 2 AND 3)
{
set Task table completetionStatus to 'CL'
}
else if (>0% but <100% of subTaskCompletionStatus = 2 or 3)
{
set Task table completetionStatus to 'PC'
}
else if(100% of subTaskCompletionStatus >= 4)
{
set Task table completetionStatus to 'F'
}
Ultimatly I need a solution for SQL Server 2005, but it would be great if a solution for SQL 2000 could also be provided. I would also like to avoid the use of triggers.
This needs to be as slick as possible as it will be a routine being hit on a very regular basis. Any solutions I come up with are either to "clunky" or I am not sure how to implement.
Let me know if you are unsure of what I am going on about!!
Many thanks for any help given.
ASKER
Hi mwvisa1
Thanks for the quick reply. I can't test your solution right now, but as soon as I have I will let you know how it has gone.
Thanks
ETFairFax
Thanks for the quick reply. I can't test your solution right now, but as soon as I have I will let you know how it has gone.
Thanks
ETFairFax
ASKER
mwvisa1
This looks like it will do just the trick, but needs a little honing.
Running the Sql in the code snippet below results in a task a task.completionStatus of 'PC' where it should be 'CL'.
I think this is down to an issue with rounding in the...
SELECT taskID
, SUM(CASE WHEN subTaskCompletionStatus <= 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(id) As countOfLTE1
, SUM(CASE WHEN subTaskCompletionStatus = 2 THEN 1 ELSE 0 END) * 100.0 / COUNT(id) As countOf2
, SUM(CASE WHEN subTaskCompletionStatus = 3 THEN 1 ELSE 0 END) * 100.0 / COUNT(id) As countOf3
, SUM(CASE WHEN subTaskCompletionStatus >= 4 THEN 1 ELSE 0 END) * 100.0 / COUNT(id) As countOfGTE4
FROM SubTask
GROUP BY taskID
... part of the procedure. I could be wrong, but from my tests so far I am getting a load of 99.999999999999 results instead of 100.00.
Can you please provide a fix for that to?
I must say I am glad I signed up to EE. This is my first post and am impressed with the reponse.
Many thanks,
ETFairfax
This looks like it will do just the trick, but needs a little honing.
Running the Sql in the code snippet below results in a task a task.completionStatus of 'PC' where it should be 'CL'.
I think this is down to an issue with rounding in the...
SELECT taskID
, SUM(CASE WHEN subTaskCompletionStatus <= 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(id) As countOfLTE1
, SUM(CASE WHEN subTaskCompletionStatus = 2 THEN 1 ELSE 0 END) * 100.0 / COUNT(id) As countOf2
, SUM(CASE WHEN subTaskCompletionStatus = 3 THEN 1 ELSE 0 END) * 100.0 / COUNT(id) As countOf3
, SUM(CASE WHEN subTaskCompletionStatus >= 4 THEN 1 ELSE 0 END) * 100.0 / COUNT(id) As countOfGTE4
FROM SubTask
GROUP BY taskID
... part of the procedure. I could be wrong, but from my tests so far I am getting a load of 99.999999999999 results instead of 100.00.
Can you please provide a fix for that to?
I must say I am glad I signed up to EE. This is my first post and am impressed with the reponse.
Many thanks,
ETFairfax
IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_SubTask_Task]') AND parent_object_id = OBJECT_ID(N'[dbo].[SubTask]'))
ALTER TABLE [dbo].[SubTask] DROP CONSTRAINT [FK_SubTask_Task]
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[SubTask]') AND type in (N'U'))
DROP TABLE [dbo].[SubTask]
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Task]') AND type in (N'U'))
DROP TABLE [dbo].[Task]
CREATE TABLE [dbo].[Task]
(
[id] [int] IDENTITY(1,1) NOT NULL,
[name] [nvarchar](50) NOT NULL,
[completetionStatus] [nvarchar](10) NOT NULL,
CONSTRAINT [PK_Task] PRIMARY KEY CLUSTERED ([id] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[SubTask]
(
[id] [int] IDENTITY(1,1) NOT NULL,
[taskId] [int] NOT NULL,
[subTaskCompletionStatus] [int] NOT NULL,
CONSTRAINT [PK_SubTask] PRIMARY KEY CLUSTERED ([id] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
ON [PRIMARY]
ALTER TABLE [dbo].[SubTask] WITH CHECK ADD CONSTRAINT [FK_SubTask_Task] FOREIGN KEY([taskId])
REFERENCES [dbo].[Task] ([id])
ALTER TABLE [dbo].[SubTask] CHECK CONSTRAINT [FK_SubTask_Task]
INSERT INTO [Task] ([name], [completetionStatus]) VALUES ('Task 01', 'S');
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (1, 2);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (1, 2);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (1, 2);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (1, 2);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (1, 2);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (1, 3);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (1, 3);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (1, 3);
INSERT INTO [SubTask] ([taskId], [subTaskCompletionStatus]) VALUES (1, 3);
EXEC UpdateTask 1
SELECT * FROM Task
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
And you are most welcome and glad to have you here at EE.
ASKER
Nice one, your solution worked a treat. Thanks very much.
Try this (see code snippet).
Usage:
EXEC dbo.updateTask 1
Hopefully that helps and is clear.
Regards,
mwvisa1
Open in new window