Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
X-Factor
Constraint Violating Yak Guru
392 Posts |
Posted - 2006-01-05 : 13:17:47
|
| Hi,Let this be a set of rows created by a group operation but before the aggregate has been applied...Order, Allow============1 null2 null3 04 15 0Now, starting with the lowest order, I want to return the first non-null value of allow.So given the above table, my final group row after the aggregate function has been applied should return a value of '0' for 'allow'.Conversely, 'Max(Allow)' will give '1' which is wrong. The row with order 3 should override this value with a '0'.Is it possible to have an aggregate function which does this?Cheers, XF. |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2006-01-05 : 13:33:33
|
If I understand you correctly, you really don't want min or max allow. You want allow for the min and max order, correct?use northwindset nocount ongocreate table junk ([order] int identity(1,1) primary key ,allow bit null)goinsert junk (allow)select null union allselect null union allselect 0 union allselect 1 union allselect 0select a.allow [minAllow]from junk ajoin ( select min([order]) [order] from junk where allow is not null ) b on b.[order] = a.[order]select a.allow [maxAllow]from junk ajoin ( select max([order]) [order] from junk where allow is not null ) b on b.[order] = a.[order]godrop table junk Be One with the OptimizerTG |
 |
|
|
X-Factor
Constraint Violating Yak Guru
392 Posts |
Posted - 2006-01-05 : 16:15:52
|
I want allow for the min order where allow is not null.However, I want this for all the different groups created by grouping a relation. So in your example, junk would be just one group and as far as I know its not possible to apply relational operators to a group. You can only use aggregate functions on columns.So if your junk table has an extra column so that it becomes...create table junk (groupID int ,allow bit null, order int) ...and there's a different order for each group. Then I don't think its possible to get allow for the min order of each group from the following...select groupID, allow ??from junkgroup by groupID |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2006-01-05 : 16:29:59
|
| That may be true, I was just working off your initial table structure and sample data. Post the actual structure with some sample data along with your desired results and we'll see.Be One with the OptimizerTG |
 |
|
|
X-Factor
Constraint Violating Yak Guru
392 Posts |
Posted - 2006-01-05 : 16:51:36
|
Here's a table of permissions...CREATE TABLE [dbo].[tbl_Folders_Groups_Permissions] ( [FolderID] [int] NOT NULL , [GroupID] [int] NOT NULL , [FolderPermissionID] [int] NOT NULL , [Allow] [bit] NOT NULL ) ON [PRIMARY]GO Here's a sp which given a folder and a group iterates up the hierarchy to get the set of all folders in the path.ALTER PROCEDURE sp_GetFolderPermissionsForGroup @folderID int, @groupID intAS-- declare variablesDECLARE @resultSet table ( folderPermissionID int, ordering int )DECLARE @parentID intDECLARE @ACounterVariable intSET @ACounterVariable = 1--loop until a top level node has been reached or the loop is apparently stuckWHILE (@ACounterVariable < 10000) BEGIN -- accumulate results in table variable INSERT INTO @resultSet ( folderID, ordering ) VALUES ( @folderID, @ACounterVariable ) --get data for next level SELECT @parentID = ParentID FROM tbl_Folders WHERE FolderID = @folderID --check to see if a top of node has been reached IF @parentID IS NULL BREAK --update SET @folderID = @parentID -- increment counter SET @ACounterVariable = @ACounterVariable + 1 END Then I was hoping to join the path to the permissions table...SELECT FolderPermissionID, Allow ??FROM @resultSet rJOIN tbl_Folders_Groups_Permissions fON f.FolderID = r.folderID AND f.GroupID = @groupIDGROUP BY FolderPermissionID If this isn't possible then I'm planning to get all the permissions for each folder one by one upon each iteration up the path and accumulate the permissions in a table variable. I just think this will be alot more work for the db to do. |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2006-01-05 : 17:20:38
|
Sorry X, I'm being thick. Could you provide a couple sample rows and the expected results?Something like this:insert [tbl_Folders_Groups_Permissions]select 1,1,1,1 union allselect 2,1,2,nullselect...--Contents of @resultSet after the loopinginsert @resultSet select ...expected Results:FolderPermissionID Allow------------------ ------- 1 1 2 0 Be One with the OptimizerTG |
 |
|
|
X-Factor
Constraint Violating Yak Guru
392 Posts |
Posted - 2006-01-05 : 18:13:58
|
Well I've got it working with what I think is a slower method but hopefully it should illustrate what I'm after...use tempdbCREATE TABLE tbl_FolderPermissions ( [FolderPermissionID] [int] NOT NULL , [PermissionName] [varchar] (50) NOT NULL) ON [PRIMARY]CREATE TABLE tbl_Folders ( [FolderID] [int] NOT NULL , [ParentID] [int] NULL , [FolderName] [varchar] (100) NOT NULL , [CascadePermissions] [bit] NOT NULL ) ON [PRIMARY]CREATE TABLE tbl_Folders_Groups_Permissions ( [FolderID] [int] NOT NULL , [GroupID] [int] NOT NULL , [FolderPermissionID] [int] NOT NULL , [Allow] [bit] NOT NULL ) ON [PRIMARY]INSERT tbl_FolderPermissionsSELECT 1, 'Upload file' UNION ALLSELECT 2, 'Delete file' UNION ALLSELECT 3, 'Create folder'INSERT tbl_FoldersSELECT 1, null, 'Parent Folder', 1 UNION ALLSELECT 2, 1, 'Child Folder', 1INSERT tbl_Folders_Groups_PermissionsSELECT 2, 1, 1, 0 UNION ALLSELECT 1, 1, 1, 1 UNION ALLSELECT 1, 1, 2, 1GOCREATE PROCEDURE sp_GetFolderPermissionsForGroup @folderID int, @groupID intAS-- declare variablesDECLARE @resultSet table ( folderPermissionID int, allow bit )INSERT INTO @resultSet SELECT folderPermissionID, null FROM tbl_FolderPermissionsDECLARE @parentID intDECLARE @allowCascade bitDECLARE @ACounterVariable intSET @ACounterVariable = 1--loop until a top level node has been reached or the loop is apparently stuckWHILE (@ACounterVariable < 10000) BEGIN UPDATE @resultSet SET allow = CASE WHEN r.allow IS NULL AND p.allow IS NOT NULL THEN p.allow ELSE r.allow END FROM @resultSet r, tbl_Folders_Groups_Permissions p WHERE r.folderPermissionID = p.FolderPermissionID AND p.FolderID = @folderID AND p.GroupID = @groupID --get data for next level SELECT @parentID = f1.ParentID, @allowCascade = f2.CascadePermissions FROM tbl_Folders f1 LEFT JOIN tbl_Folders f2 ON f1.ParentID = f2.FolderID WHERE f1.FolderID = @folderID --check to see if a top of node has been reached IF @parentID IS NULL OR @allowCascade = 0 BREAK --update SET @folderID = @parentID -- increment counter SET @ACounterVariable = @ACounterVariable + 1 ENDSELECT r.*, f.PermissionName FROM @resultSet r JOIN tbl_FolderPermissions f on r.FolderPermissionID = f.FolderPermissionIDGOEXECUTE sp_GetFolderPermissionsForGroup 2, 1drop PROCEDURE sp_GetFolderPermissionsForGroupdrop table tbl_FolderPermissionsdrop table tbl_Foldersdrop table tbl_Folders_Groups_Permissions So you can see that folder 2 inherits folder 1's allow value for permission 2 but has its own allow value for permission 1. Permission 3 defaults to a no as a result of it being null.The original question is about having the sp only get the folder's in the path when it iterates up the hierarchy and then using this set resolve the correct allow value in one query.I hope this is making a bit more sense! |
 |
|
|
|
|
|
|
|