Partitioned Sequence / Identity - sql-server

Given a table like this
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[_bh_test](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Agency] [int] NOT NULL,
[Year] [int] NULL,
[Num] [int] NOT NULL
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[_bh_test] ON
GO
INSERT [dbo].[_bh_test] ([Id], [Agency], [Year], [Num]) VALUES (1, 1, 2015, 1)
GO
INSERT [dbo].[_bh_test] ([Id], [Agency], [Year], [Num]) VALUES (2, 1, 2015, 2)
GO
INSERT [dbo].[_bh_test] ([Id], [Agency], [Year], [Num]) VALUES (3, 1, 2016, 1)
GO
INSERT [dbo].[_bh_test] ([Id], [Agency], [Year], [Num]) VALUES (4, 2, 2015, 1)
GO
INSERT [dbo].[_bh_test] ([Id], [Agency], [Year], [Num]) VALUES (5, 2, 2015, 2)
GO
INSERT [dbo].[_bh_test] ([Id], [Agency], [Year], [Num]) VALUES (6, 2, 2016, 1)
GO
INSERT [dbo].[_bh_test] ([Id], [Agency], [Year], [Num]) VALUES (7, 2, 2016, 2)
GO
INSERT [dbo].[_bh_test] ([Id], [Agency], [Year], [Num]) VALUES (8, 3, 2015, 1)
GO
INSERT [dbo].[_bh_test] ([Id], [Agency], [Year], [Num]) VALUES (9, 3, 2015, 2)
GO
INSERT [dbo].[_bh_test] ([Id], [Agency], [Year], [Num]) VALUES (10, 3, 2016, 2)
GO
SET IDENTITY_INSERT [dbo].[_bh_test] OFF
GO
/****** Object: Index [UIX_Agency_Year_Num] Script Date: 4/17/2017 10:42:15 PM ******/
CREATE UNIQUE NONCLUSTERED INDEX [UIX_Agency_Year_Num] ON [dbo].[_bh_test]
(
[Agency] ASC,
[Year] ASC,
[Num] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
I want the Num column to always have a value that is unique across that particular Agency when inserting. Additionally, I want it to be a number that has never been used before.
So for example if I am inserting a value with agency 3, then a good candidate for Num would be 3.
It would seem I could use a default/binding to a function that would take the MAX(Num) + 1 with a group by for Agency. However, I wasnt able to send in the Agency to the function. But futhermore if the MAX(Num) was 2 and I inserted in 3...Then deleted 3, and inserted again it would reuse a Num of 3, which is wrong because I only want it to use a Num that has never been used before.
It sounds like an ideal solution for me would be a sequence that keeps track of a counter. Although it seems I cant used the PARTITION BY in the OVER in a SEQUENCE. Also the Num may be set manually so If the sequence was +1, and two values were inserted using the default seq. so now counter is at 2...it may be that 3 is manually inserted, and then next insert by default would be 3. I would have to make sure to update the sequence on INSERT
I am not sure the best approach. I think using an INSERT TRIGGER is an option but I am not sure how to get around the whole problem if the MAX() is deleted and an INSERT is done.

Related

Using PIVOT without any aggregate function

I have this table structure that store's employee's attendance daily. I want to get the result so that I could know under the date how many times employee marked attendance if it was checkin it'll give any status let's say IN and if it was checkout it'll say OUT in separate column.
/****** Object: Table [dbo].[Attendance] Script Date: 4/24/2019 2:22:47 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Attendance](
[EmpCode] [int] NULL,
[TimeIn] [datetime] NULL,
[TimeOut] [datetime] NULL
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[Employee] Script Date: 4/24/2019 2:22:47 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Employee](
[ID] [int] NOT NULL,
[EmployeeName] [varchar](25) NULL,
[Department] [varchar](25) NULL,
[CenterCode] [int] NULL,
CONSTRAINT [PK_Employee] 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]
GO
SET ANSI_PADDING OFF
GO
INSERT [dbo].[Attendance] ([EmpCode], [TimeIn], [TimeOut]) VALUES (1, CAST(N'2019-02-01 06:30:00.000' AS DateTime), NULL)
GO
INSERT [dbo].[Attendance] ([EmpCode], [TimeIn], [TimeOut]) VALUES (1, NULL, CAST(N'2019-02-01 18:22:00.000' AS DateTime))
GO
INSERT [dbo].[Attendance] ([EmpCode], [TimeIn], [TimeOut]) VALUES (1, CAST(N'2019-02-02 07:21:00.000' AS DateTime), NULL)
GO
INSERT [dbo].[Attendance] ([EmpCode], [TimeIn], [TimeOut]) VALUES (1, NULL, CAST(N'2019-02-02 19:54:00.000' AS DateTime))
GO
INSERT [dbo].[Employee] ([ID], [EmployeeName], [Department], [CenterCode]) VALUES (1, N'Asim', N'Information Tech', 4)
GO
INSERT [dbo].[Employee] ([ID], [EmployeeName], [Department], [CenterCode]) VALUES (2, N'Ali', N'Information Tech', 2)
GO
INSERT [dbo].[Employee] ([ID], [EmployeeName], [Department], [CenterCode]) VALUES (3, N'Isaac', N'Information Tech', 3)
GO
INSERT [dbo].[Employee] ([ID], [EmployeeName], [Department], [CenterCode]) VALUES (4, N'Swagger', N'Information Tech', 4)
GO
INSERT [dbo].[Employee] ([ID], [EmployeeName], [Department], [CenterCode]) VALUES (5, N'Nadine', N'Information Tech', 2)
GO
INSERT [dbo].[Employee] ([ID], [EmployeeName], [Department], [CenterCode]) VALUES (6, N'Julie', N'Information Tech', 4)
GO
INSERT [dbo].[Employee] ([ID], [EmployeeName], [Department], [CenterCode]) VALUES (7, N'Meachum', N'Information Tech', 3)
GO
INSERT [dbo].[Employee] ([ID], [EmployeeName], [Department], [CenterCode]) VALUES (8, N'Bob Lee', N'Information Tech', 4)
GO
ALTER TABLE [dbo].[Attendance] WITH CHECK ADD CONSTRAINT [FK_Attendance_Employee] FOREIGN KEY([EmpCode])
REFERENCES [dbo].[Employee] ([ID])
GO
ALTER TABLE [dbo].[Attendance] CHECK CONSTRAINT [FK_Attendance_Employee]
GO
Now I have wrote a query but as I'm not sure how to use PIVOT function without aggregate funciton so I'm using MIN() and that's why it's only giving me the first timein/timeout of the day.
Here is the query:
SELECT * FROM (
SELECT E.ID, E.EmployeeName, T.DateToCheck, COALESCE(A.val, 'Absent') val
FROM Employee E
CROSS JOIN (
SELECT CAST(DATEADD(DAY, number, '2019-02-01') AS DATE)
FROM master..spt_values
WHERE type = 'P'
AND DATEADD(DAY, number, '2019-02-01') <= '2019-02-28') T(DateToCheck)
LEFT JOIN (SELECT CAST(CAST(COALESCE(TimeIn, TimeOut) AS TIME) AS VARCHAR) val, CAST(COALESCE(TimeIn, TimeOut) AS DATE) AttendanceDateTime, EmpCode FROM Attendance) A ON CAST(A.AttendanceDateTime AS DATE) = T.DateToCheck AND A.EmpCode = E.ID
) T
PIVOT (MIN(val) FOR DateToCheck IN ([2019-02-01],[2019-02-02],[2019-02-03],[2019-02-04],[2019-02-05],[2019-02-06],[2019-02-07],[2019-02-08],[2019-02-09],[2019-02-10],[2019-02-11],[2019-02-12],[2019-02-13],[2019-02-14],[2019-02-15],[2019-02-16],[2019-02-17],[2019-02-18],[2019-02-19],[2019-02-20],[2019-02-21],[2019-02-22],[2019-02-23],[2019-02-24],[2019-02-25],[2019-02-26],[2019-02-27],[2019-02-28])) P;
The expected output result is something like this
EmployeeName Status 2019-02-01 2019-02-02
Asim IN 06:30 07:21
Asim OUT 11:39 19:54
Asim IN 13:06 NULL
Asim OUT 18:22 NULL

How to copy records from parent to child in same table using MS SQL CTE

I have requirement like copy same parent records to N child with same table. The only difference in the data is Parent Id and Client Id, I have to copy Parent records as it is to child with only ParentId and ClientId value change.
- Parent records may be 1 to 2000 which need to be moved for each client.
- Child records (repeat 1 to 1000) different child.
I have implemented the requirement using SQL Server Cursor but this is extensively very slow if we have parent records more than 1000 and Child (repeat entries) more than 1500. So i would like to know whether it is possible to use CTE instead cursor to gain performance for the bulk insertion.
I am using following code to copy parent records to each client:
DECLARE #id bigint;
--Get list of client which will repeat the rows from Master entries
--This will return three rows Id:1,5,7
DECLARE client_cursor CURSOR FOR SELECT Id FROM Client WHERE ClientName like 'info%'
OPEN client_cursor
FETCH NEXT FROM client_cursor INTO #id;
WHILE ##FETCH_STATUS = 0
BEGIN
/*....*/
/* Other business logic performed here */
/*....*/
INSERT INTO Resources (ParentId,ClientId,Location,Title,[Status],Alert)
--This will return two rows Id:1,2
SELECT Id,#id,Location,Title,[Status],Alert FROM Resources WHERE ParentId IS NULL AND ClientId IS NULL
FETCH NEXT FROM client_cursor INTO #id
END
CLOSE client_cursor;
DEALLOCATE client_cursor;
Following are the screen shot before and after adding bulk Parent records to Child using above code snippet.
-- Table Creation
CREATE TABLE [dbo].[Client](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[ClientName] [varchar](50) NULL,
CONSTRAINT [PK_Client] 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]
GO
CREATE TABLE [dbo].[Resources](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[ParentId] [bigint] NULL,
[ClientId] [bigint] NULL,
[Location] [varchar](50) NULL,
[Title] [varchar](50) NULL,
[Status] [varchar](50) NULL,
[Alert] [varchar](50) NULL,
CONSTRAINT [PK_Resources] 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]
GO
-- Default Data Insertion
SET IDENTITY_INSERT [dbo].[Client] ON
INSERT [dbo].[Client] ([Id], [ClientName]) VALUES (1, N'Infosstretch')
INSERT [dbo].[Client] ([Id], [ClientName]) VALUES (2, N'Microsoft')
INSERT [dbo].[Client] ([Id], [ClientName]) VALUES (3, N'Sun System')
INSERT [dbo].[Client] ([Id], [ClientName]) VALUES (4, N'IBM')
INSERT [dbo].[Client] ([Id], [ClientName]) VALUES (5, N'Infosys')
INSERT [dbo].[Client] ([Id], [ClientName]) VALUES (6, N'TCS')
INSERT [dbo].[Client] ([Id], [ClientName]) VALUES (7, N'Infomatica')
SET IDENTITY_INSERT [dbo].[Client] OFF
SET IDENTITY_INSERT [dbo].[Resources] ON
INSERT [dbo].[Resources] ([Id], [ParentId], [ClientId], [Location], [Title], [Status], [Alert]) VALUES (1, NULL, NULL, N'India', N'Master A', N'New', N'Issue with location')
INSERT [dbo].[Resources] ([Id], [ParentId], [ClientId], [Location], [Title], [Status], [Alert]) VALUES (2, NULL, NULL, N'Australia', N'Master B', N'Updated', N'No major issue')
SET IDENTITY_INSERT [dbo].[Resources] OFF
There are probably some reasons from your business rules that are removed for brevity here, but why not something like this?
INSERT #Resources
SELECT
R.Id AS ParentId,
C.Id AS ClientId,
R.Location,
R.Title,
R.Status,
R.Alert
FROM #Resources R
CROSS JOIN #Client C
WHERE R.ParentId IS NULL AND R.ClientId IS NULL -- Root level
AND NOT EXISTS (SELECT * FROM #Resources WHERE ParentId = R.Id) -- Not already populated
-- AND /* Other business logic performed here */

SQL Server CTE hierarchy issue

i have an application serve multilevel of permissions and roles
i have this HIERARCHY :
Country
....Region
........City
............Association
................Center
....................School
........................Class
this HIERARCHY i name it "EntityLevels"
| ID | Name | ParentID |
|----|-------------|----------|
| 1 | Country | Null |
| 2 | Region | 1 |
| 3 | City | 2 |
| 4 | Association | 3 |
| 5 | Center | 4 |
| 6 | School | 5 |
| 7 | Class | 6 |
i have also a Groups Table which means Jobs
| ID | Name | EntityLevels |
|----|--------------------|--------------|
| 1 | CountryAdmins | 1 |
| 2 | Region Supervisors | 2 |
the user table is as following
| ID | Name |
|----|-------|
| 1 | User1 |
| 2 | User2 |
now i have a UserJobs Table or UserGroups
| ID | UserID | GroupdID | EntityID |
|----|--------|----------|----------|
| 1 | User1 | 1 | 1 |
| 2 | User2 | 2 | 2 |
| 3 | User3 | 4 | 38 |
now the problem is how i can get each user and his responsibilites depending on what it's under his level
for eaxmple :
user1 must have all the roles and permissoins to see all users under his level because he is in Group (1) and Group1 it resides on EntityLevel (1) which it's on the Country Level.
i've try to do something like that, but it's not working as Expected it's Only give me the root without any other child under that root
;WITH MyCTE AS (
SELECT T1.ID, UserId, 0 AS TreeLevel, CAST(T1.ID AS VARCHAR(255)) AS TreePath FROM UserJobs T1
inner join EntityLevel el on t1.GroupId = el.Id WHERE EL.ParentID IS NULL
UNION ALL
SELECT T2.ID, T2.UserId, TreeLevel + 1, CAST(TreePath + '.' + CAST(T2.ID AS VARCHAR(255)) AS VARCHAR(255)) AS TreePath
FROM UserJobs T2
inner join EntityLevel el on T2.GroupId = el.Id
INNER JOIN
MyCTE itms ON itms.ID = EL.ParentID
)
SELECT ID, TreeLevel, TreePath
FROM MyCTE
ORDER BY TreePath;
Script for Schema And DATA
dbfiddle here
CREATE TABLE [dbo].[Assocation](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[CityID] [int] NULL,
CONSTRAINT [PK_Assocation] 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]
GO
/****** Object: Table [dbo].[Center] Script Date: 2017-04-03 6:07:29 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Center](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[AssociationID] [int] NULL,
CONSTRAINT [PK_Center] 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]
GO
/****** Object: Table [dbo].[City] Script Date: 2017-04-03 6:07:29 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[City](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[RegionID] [int] NULL,
CONSTRAINT [PK_City] 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]
GO
/****** Object: Table [dbo].[Class] Script Date: 2017-04-03 6:07:29 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Class](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[SchoolID] [int] NULL,
CONSTRAINT [PK_Class] 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]
GO
/****** Object: Table [dbo].[Country] Script Date: 2017-04-03 6:07:29 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Country](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
CONSTRAINT [PK_Country] 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]
GO
/****** Object: Table [dbo].[EntityLevel] Script Date: 2017-04-03 6:07:29 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[EntityLevel](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[ParentID] [int] NULL,
CONSTRAINT [PK_Table_1] 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]
GO
/****** Object: Table [dbo].[Group] Script Date: 2017-04-03 6:07:29 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Group](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[EntityLevelID] [int] NULL,
CONSTRAINT [PK_Group] 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]
GO
/****** Object: Table [dbo].[Region] Script Date: 2017-04-03 6:07:29 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Region](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[CountryID] [int] NULL,
CONSTRAINT [PK_Region] 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]
GO
/****** Object: Table [dbo].[School] Script Date: 2017-04-03 6:07:29 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[School](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[CenterID] [int] NULL,
CONSTRAINT [PK_School] 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]
GO
/****** Object: Table [dbo].[User] Script Date: 2017-04-03 6:07:29 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[User](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[Mobile] [varchar](50) NULL,
CONSTRAINT [PK_User] 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]
GO
/****** Object: Table [dbo].[UserJobs] Script Date: 2017-04-03 6:07:29 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[UserJobs](
[ID] [int] NOT NULL,
[UserID] [int] NOT NULL,
[GroupID] [int] NOT NULL,
[EntityID] [int] NOT NULL,
CONSTRAINT [PK_UserJobs] PRIMARY KEY CLUSTERED
(
[ID] ASC,
[UserID] ASC,
[GroupID] ASC,
[EntityID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT [dbo].[Assocation] ([ID], [Name], [CityID]) VALUES (1, N'KH', 1)
GO
INSERT [dbo].[Assocation] ([ID], [Name], [CityID]) VALUES (2, N'mkh_ass', 2)
GO
INSERT [dbo].[Center] ([ID], [Name], [AssociationID]) VALUES (1, N'NorthCenter', 1)
GO
INSERT [dbo].[Center] ([ID], [Name], [AssociationID]) VALUES (2, N'SouthCenter', 1)
GO
INSERT [dbo].[City] ([ID], [Name], [RegionID]) VALUES (1, N'Jeddah', 1)
GO
INSERT [dbo].[City] ([ID], [Name], [RegionID]) VALUES (2, N'MakkahCiry', 1)
GO
INSERT [dbo].[Class] ([ID], [Name], [SchoolID]) VALUES (1, N'Class1-Ahmed', 1)
GO
INSERT [dbo].[Class] ([ID], [Name], [SchoolID]) VALUES (2, N'Class2-omar', 1)
GO
INSERT [dbo].[Class] ([ID], [Name], [SchoolID]) VALUES (3, N'class3_khaled', 2)
GO
INSERT [dbo].[Class] ([ID], [Name], [SchoolID]) VALUES (4, N'class4_fahd', 2)
GO
INSERT [dbo].[Country] ([ID], [Name]) VALUES (1, N'KSA')
GO
INSERT [dbo].[Country] ([ID], [Name]) VALUES (2, N'UAE')
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (1, N'Country', NULL)
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (2, N'Region', 1)
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (3, N'City', 2)
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (4, N'Association', 3)
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (5, N'Center', 4)
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (6, N'School', 5)
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (7, N'Class', 6)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (1, N'SA', 1)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (2, N'country admin', 1)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (3, N'region admin', 2)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (4, N'region Supervisor', 2)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (5, N'manager', 4)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (6, N'supervisor', 5)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (7, N'teacher', 7)
GO
INSERT [dbo].[Region] ([ID], [Name], [CountryID]) VALUES (1, N'Makkah', 1)
GO
INSERT [dbo].[Region] ([ID], [Name], [CountryID]) VALUES (2, N'Riyadh', 1)
GO
INSERT [dbo].[School] ([ID], [Name], [CenterID]) VALUES (1, N'School1', 1)
GO
INSERT [dbo].[School] ([ID], [Name], [CenterID]) VALUES (2, N'School2', 1)
GO
INSERT [dbo].[School] ([ID], [Name], [CenterID]) VALUES (3, N'School3', 2)
GO
INSERT [dbo].[User] ([ID], [Name], [Mobile]) VALUES (1, N'Loai', N'000000')
GO
INSERT [dbo].[User] ([ID], [Name], [Mobile]) VALUES (2, N'User1', N'1111')
GO
INSERT [dbo].[User] ([ID], [Name], [Mobile]) VALUES (3, N'User2', N'2222')
GO
INSERT [dbo].[User] ([ID], [Name], [Mobile]) VALUES (4, N'User3', N'3333')
GO
INSERT [dbo].[User] ([ID], [Name], [Mobile]) VALUES (5, N'User4', N'4444')
GO
INSERT [dbo].[User] ([ID], [Name], [Mobile]) VALUES (6, N'user5', N'5555')
GO
INSERT [dbo].[User] ([ID], [Name], [Mobile]) VALUES (7, N'user6', N'6548')
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (1, 1, 1, 1)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (2, 2, 2, 1)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (3, 3, 3, 1)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (4, 4, 4, 1)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (5, 5, 5, 2)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (6, 6, 6, 1)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (7, 7, 7, 2)
GO
(EDIT) : The Expected Result will be :
SCRIPT AND DATA VERSION #2
CREATE TABLE [dbo].[Assocation](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[CityID] [int] NULL,
CONSTRAINT [PK_Assocation] 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]
GO
/****** Object: Table [dbo].[Center] Script Date: 2017-04-04 3:47:05 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Center](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[AssociationID] [int] NULL,
CONSTRAINT [PK_Center] 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]
GO
/****** Object: Table [dbo].[City] Script Date: 2017-04-04 3:47:05 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[City](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[RegionID] [int] NULL,
CONSTRAINT [PK_City] 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]
GO
/****** Object: Table [dbo].[Class] Script Date: 2017-04-04 3:47:05 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Class](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[SchoolID] [int] NULL,
CONSTRAINT [PK_Class] 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]
GO
/****** Object: Table [dbo].[Country] Script Date: 2017-04-04 3:47:05 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Country](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
CONSTRAINT [PK_Country] 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]
GO
/****** Object: Table [dbo].[EntityLevel] Script Date: 2017-04-04 3:47:05 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[EntityLevel](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[ParentID] [int] NULL,
CONSTRAINT [PK_Table_1] 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]
GO
/****** Object: Table [dbo].[Group] Script Date: 2017-04-04 3:47:05 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Group](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[EntityLevelID] [int] NULL,
CONSTRAINT [PK_Group] 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]
GO
/****** Object: Table [dbo].[Region] Script Date: 2017-04-04 3:47:05 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Region](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[CountryID] [int] NULL,
CONSTRAINT [PK_Region] 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]
GO
/****** Object: Table [dbo].[School] Script Date: 2017-04-04 3:47:05 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[School](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[CenterID] [int] NULL,
CONSTRAINT [PK_School] 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]
GO
/****** Object: Table [dbo].[User] Script Date: 2017-04-04 3:47:05 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[User](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[Mobile] [varchar](50) NULL,
CONSTRAINT [PK_User] 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]
GO
/****** Object: Table [dbo].[UserJobs] Script Date: 2017-04-04 3:47:05 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[UserJobs](
[ID] [int] NOT NULL,
[UserID] [int] NOT NULL,
[GroupID] [int] NOT NULL,
[EntityID] [int] NOT NULL,
CONSTRAINT [PK_UserJobs] PRIMARY KEY CLUSTERED
(
[ID] ASC,
[UserID] ASC,
[GroupID] ASC,
[EntityID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT [dbo].[Assocation] ([ID], [Name], [CityID]) VALUES (1, N'KH', 1)
GO
INSERT [dbo].[Assocation] ([ID], [Name], [CityID]) VALUES (2, N'mkh_ass', 2)
GO
INSERT [dbo].[Center] ([ID], [Name], [AssociationID]) VALUES (1, N'NorthCenter', 1)
GO
INSERT [dbo].[Center] ([ID], [Name], [AssociationID]) VALUES (2, N'SouthCenter', 1)
GO
INSERT [dbo].[City] ([ID], [Name], [RegionID]) VALUES (1, N'Jeddah', 1)
GO
INSERT [dbo].[City] ([ID], [Name], [RegionID]) VALUES (2, N'MakkahCiry', 1)
GO
INSERT [dbo].[Class] ([ID], [Name], [SchoolID]) VALUES (1, N'Class1', 1)
GO
INSERT [dbo].[Class] ([ID], [Name], [SchoolID]) VALUES (2, N'Class2', 1)
GO
INSERT [dbo].[Class] ([ID], [Name], [SchoolID]) VALUES (3, N'class3', 2)
GO
INSERT [dbo].[Class] ([ID], [Name], [SchoolID]) VALUES (4, N'class4', 2)
GO
INSERT [dbo].[Country] ([ID], [Name]) VALUES (1, N'KSA')
GO
INSERT [dbo].[Country] ([ID], [Name]) VALUES (2, N'UAE')
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (1, N'Country', NULL)
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (2, N'Region', 1)
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (3, N'City', 2)
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (4, N'Association', 3)
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (5, N'Center', 4)
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (6, N'School', 5)
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (7, N'Class', 6)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (1, N'Country Manager', 1)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (2, N'Region Manager', 2)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (3, N'City Manager', 3)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (4, N'Association Manager', 4)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (5, N'Center Manager', 5)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (6, N'School Manager', 6)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (7, N'Teacher', 7)
GO
INSERT [dbo].[Region] ([ID], [Name], [CountryID]) VALUES (1, N'Makkah', 1)
GO
INSERT [dbo].[Region] ([ID], [Name], [CountryID]) VALUES (2, N'Riyadh', 1)
GO
INSERT [dbo].[School] ([ID], [Name], [CenterID]) VALUES (1, N'School1', 1)
GO
INSERT [dbo].[School] ([ID], [Name], [CenterID]) VALUES (2, N'School2', 1)
GO
INSERT [dbo].[School] ([ID], [Name], [CenterID]) VALUES (3, N'School3', 2)
GO
INSERT [dbo].[User] ([ID], [Name], [Mobile]) VALUES (1, N'UserA', N'000000')
GO
INSERT [dbo].[User] ([ID], [Name], [Mobile]) VALUES (2, N'UserB', N'1111')
GO
INSERT [dbo].[User] ([ID], [Name], [Mobile]) VALUES (3, N'UserC', N'2222')
GO
INSERT [dbo].[User] ([ID], [Name], [Mobile]) VALUES (4, N'UserD', N'3333')
GO
INSERT [dbo].[User] ([ID], [Name], [Mobile]) VALUES (5, N'UserE', N'4444')
GO
INSERT [dbo].[User] ([ID], [Name], [Mobile]) VALUES (6, N'UserF', N'5555')
GO
INSERT [dbo].[User] ([ID], [Name], [Mobile]) VALUES (7, N'UserG', N'6548')
GO
INSERT [dbo].[User] ([ID], [Name], [Mobile]) VALUES (8, N'UserH', NULL)
GO
INSERT [dbo].[User] ([ID], [Name], [Mobile]) VALUES (9, N'UserI', NULL)
GO
INSERT [dbo].[User] ([ID], [Name], [Mobile]) VALUES (10, N'UserJ', NULL)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (1, 1, 1, 1)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (2, 2, 2, 1)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (3, 3, 3, 1)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (4, 4, 4, 1)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (5, 5, 5, 1)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (6, 6, 6, 1)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (7, 7, 7, 1)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (8, 8, 2, 2)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (9, 9, 3, 2)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (10, 10, 4, 2)
GO
any solution for that ?
IMHO you must build the whole Entities tree and then use it to JOIN with the other tables.
Having a look at your desired result it is not clear to me what is the relation between Entities and Cities, Regions, Class, etc.
Obviously according to the Name of the entity, I know that 1 = Country, 2 = Region and so on, but I can't find out any field on your table schema that allow to get this information other than:
CASE WHEN Entity.ID = 1 (SELECT Name FROM Country WHERE ID = Entity.ID) END
WHEN Entity.ID = 2 (SELECT Name FROM Region WHERE ID = Entity.ID) END
WHEN Entity.ID = 3 (SELECT Name FROM City WHERE ID = Entity.ID) END
...
END as EntityName
I'd suggest you to build a UDF or SP to get the name of the Entity and use it on the next script.
;WITH tree AS
(
SELECT e1.ID, e1.Name, e1.ParentID, [level] = 1
FROM EntityLevel e1
WHERE e1.ParentID = (SELECT EntityID FROM UserJobs WHERE UserID = 1)
UNION ALL
SELECT e2.ID, e2.Name, e2.ParentID, [level] = tree.[level] + 1
FROM EntityLevel e2
INNER JOIN tree
ON e2.ParentID = tree.ID
)
SELECT EntityLevelID, UserName, GroupID, GroupName, EntityID, EntityName
FROM tree t
INNER JOIN (SELECT gr.entitylevelid,
us.Name UserName,
gr.Name GroupName,
el.Name as EntityName,
gr.ID as GroupID,
el.ID as EntityID
FROM userjobs uj
INNER JOIN [group] gr
ON gr.id = uj.groupid
INNER JOIN entitylevel el
ON el.id = gr.entitylevelid
INNER JOIN [user] us
ON us.id = uj.userid) t1
ON t.ID = t1.EntityLevelID
OPTION (MAXRECURSION 0)
;
GO
EntityLevelID | UserName | GroupID | GroupName | EntityID | EntityName
------------: | :------- | ------: | :---------------- | -------: | :----------
2 | User2 | 3 | region admin | 2 | Region
2 | User3 | 4 | region Supervisor | 2 | Region
4 | User4 | 5 | manager | 4 | Association
5 | user5 | 6 | supervisor | 5 | Center
7 | user6 | 7 | teacher | 7 | Class
dbfiddle here
Can you try this? (edited after comments)
;WITH MyCTE AS (
SELECT T1.ID, UserId, NULL AS PARENT_ID, T1.GroupID, G.EntityLevelID
FROM UserJobs T1
INNER JOIN [GROUP] G ON T1.GROUPID = G.ID
inner join EntityLevel el on G.EntityLevelID = el.Id
WHERE T1.UserID = 1 /* Write here the user id you want */
UNION ALL
SELECT T2.ID, T2.UserId, EL.ParentID, T2.GroupID, G.EntityLevelID
FROM UserJobs T2
INNER JOIN [GROUP] G ON T2.GROUPID = G.ID
inner join EntityLevel el on G.EntityLevelID = el.Id
INNER JOIN MyCTE itms ON EL.ParentID >= itms.ID
)
SELECT B.*, C.*, A.*
FROM (SELECT DISTINCT * FROM MyCTE) A
INNER JOIN [USER] B ON A.UserID = B.ID
INNER JOIN [Group] C ON A.GroupID = C.ID
;
Output:
ID Name Mobile ID Name EntityLevelID ID UserId PARENT_ID GroupID EntityLevelID
1 1 Loai 000000 1 SA 1 1 1 NULL 1 1
2 3 User2 2222 3 region admin 2 3 3 1 3 2
3 4 User3 3333 4 region Supervisor 2 4 4 1 4 2
4 5 User4 4444 5 manager 4 5 5 3 5 4
5 6 user5 5555 6 supervisor 5 6 6 4 6 5
6 7 user6 6548 7 teacher 7 7 7 6 7 7

Wrong Result in the CTE Hierarchical Tree

I've this Tree
Country
Region
City
Association
Center
School
Class
i have this Query here
;WITH MyCTE AS
(
SELECT T1.ID, UserId, NULL AS PARENT_ID, T1.GroupID, G.EntityLevelID
FROM UserJobs T1
INNER JOIN [GROUP] G ON T1.GROUPID = G.ID
inner join EntityLevel el on G.EntityLevelID = el.Id
WHERE T1.UserID = 1
UNION ALL
SELECT T2.ID, T2.UserId, EL.ParentID, T2.GroupID, G.EntityLevelID
FROM UserJobs T2
INNER JOIN [GROUP] G ON T2.GROUPID = G.ID
inner join EntityLevel el on G.EntityLevelID = el.Id
INNER JOIN MyCTE itms ON EL.ParentID >= itms.ID
)
SELECT B.*, C.*, A.*
FROM (SELECT DISTINCT * FROM MyCTE) A
INNER JOIN [USER] B ON A.UserID = B.ID
INNER JOIN [Group] C ON A.GroupID = C.ID
order by a.GroupID ;
if i run this query for userID = 1
it will gives me correct Data (it will bring all the users that are under UserA = UserID = 1)
1 UserA 1 Country Manager 1 1 1 NULL 1 1
2 UserB 2 Region Manager 2 2 2 1 2 2
8 UserH 2 Region Manager 2 8 8 1 2 2
3 UserC 3 City Manager 3 3 3 2 3 3
9 UserI 3 City Manager 3 9 9 2 3 3
4 UserD 4 Association Manager 4 4 4 3 4 4
10 UserJ 4 Association Manager 4 10 10 3 4 4
5 UserE 5 Center Manager 5 5 5 4 5 5
6 UserF 6 School Manager 6 6 6 5 6 6
7 UserG 7 Teacher 7 7 7 6 7 7
this is actually what i looking for, but the problem comes when i need to get the user under UserI ID equal 9
The Result is :
9 UserI 3 City Manager 3 9 9 NULL 3 3
and that's wrong because UserI has one user Under him which is UserJ
so, the result must looks like
9 UserI 3 City Manager 3 9 9 NULL 3 3
10 UserJ 4 Association Manager 4 10 10 NULL 4 4
same error Occurs in UserID = 3 which gives me a UserJ which is out of tree
Script And Data is Here :
CREATE TABLE [dbo].[Assocation](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[CityID] [int] NULL,
CONSTRAINT [PK_Assocation] 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]
GO
/****** Object: Table [dbo].[Center] Script Date: 2017-04-04 8:33:43 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Center](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[AssociationID] [int] NULL,
CONSTRAINT [PK_Center] 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]
GO
/****** Object: Table [dbo].[City] Script Date: 2017-04-04 8:33:43 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[City](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[RegionID] [int] NULL,
CONSTRAINT [PK_City] 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]
GO
/****** Object: Table [dbo].[Class] Script Date: 2017-04-04 8:33:43 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Class](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[SchoolID] [int] NULL,
CONSTRAINT [PK_Class] 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]
GO
/****** Object: Table [dbo].[Country] Script Date: 2017-04-04 8:33:43 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Country](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
CONSTRAINT [PK_Country] 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]
GO
/****** Object: Table [dbo].[EntityLevel] Script Date: 2017-04-04 8:33:43 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[EntityLevel](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[ParentID] [int] NULL,
CONSTRAINT [PK_Table_1] 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]
GO
/****** Object: Table [dbo].[Group] Script Date: 2017-04-04 8:33:43 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Group](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[EntityLevelID] [int] NULL,
CONSTRAINT [PK_Group] 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]
GO
/****** Object: Table [dbo].[Region] Script Date: 2017-04-04 8:33:43 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Region](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[CountryID] [int] NULL,
CONSTRAINT [PK_Region] 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]
GO
/****** Object: Table [dbo].[School] Script Date: 2017-04-04 8:33:43 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[School](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[CenterID] [int] NULL,
CONSTRAINT [PK_School] 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]
GO
/****** Object: Table [dbo].[User] Script Date: 2017-04-04 8:33:43 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[User](
[ID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
CONSTRAINT [PK_User] 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]
GO
/****** Object: Table [dbo].[UserJobs] Script Date: 2017-04-04 8:33:43 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[UserJobs](
[ID] [int] NOT NULL,
[UserID] [int] NOT NULL,
[GroupID] [int] NOT NULL,
[EntityID] [int] NOT NULL,
CONSTRAINT [PK_UserJobs] PRIMARY KEY CLUSTERED
(
[ID] ASC,
[UserID] ASC,
[GroupID] ASC,
[EntityID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT [dbo].[Assocation] ([ID], [Name], [CityID]) VALUES (1, N'KH', 1)
GO
INSERT [dbo].[Assocation] ([ID], [Name], [CityID]) VALUES (2, N'mkh_ass', 2)
GO
INSERT [dbo].[Center] ([ID], [Name], [AssociationID]) VALUES (1, N'NorthCenter', 1)
GO
INSERT [dbo].[Center] ([ID], [Name], [AssociationID]) VALUES (2, N'SouthCenter', 1)
GO
INSERT [dbo].[City] ([ID], [Name], [RegionID]) VALUES (1, N'Jeddah', 1)
GO
INSERT [dbo].[City] ([ID], [Name], [RegionID]) VALUES (2, N'MakkahCiry', 1)
GO
INSERT [dbo].[Class] ([ID], [Name], [SchoolID]) VALUES (1, N'Class1', 1)
GO
INSERT [dbo].[Class] ([ID], [Name], [SchoolID]) VALUES (2, N'Class2', 1)
GO
INSERT [dbo].[Class] ([ID], [Name], [SchoolID]) VALUES (3, N'class3', 2)
GO
INSERT [dbo].[Class] ([ID], [Name], [SchoolID]) VALUES (4, N'class4', 2)
GO
INSERT [dbo].[Country] ([ID], [Name]) VALUES (1, N'KSA')
GO
INSERT [dbo].[Country] ([ID], [Name]) VALUES (2, N'UAE')
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (1, N'Country', NULL)
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (2, N'Region', 1)
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (3, N'City', 2)
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (4, N'Association', 3)
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (5, N'Center', 4)
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (6, N'School', 5)
GO
INSERT [dbo].[EntityLevel] ([ID], [Name], [ParentID]) VALUES (7, N'Class', 6)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (1, N'Country Manager', 1)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (2, N'Region Manager', 2)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (3, N'City Manager', 3)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (4, N'Association Manager', 4)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (5, N'Center Manager', 5)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (6, N'School Manager', 6)
GO
INSERT [dbo].[Group] ([ID], [Name], [EntityLevelID]) VALUES (7, N'Teacher', 7)
GO
INSERT [dbo].[Region] ([ID], [Name], [CountryID]) VALUES (1, N'Makkah', 1)
GO
INSERT [dbo].[Region] ([ID], [Name], [CountryID]) VALUES (2, N'Riyadh', 1)
GO
INSERT [dbo].[School] ([ID], [Name], [CenterID]) VALUES (1, N'School1', 1)
GO
INSERT [dbo].[School] ([ID], [Name], [CenterID]) VALUES (2, N'School2', 1)
GO
INSERT [dbo].[School] ([ID], [Name], [CenterID]) VALUES (3, N'School3', 2)
GO
INSERT [dbo].[User] ([ID], [Name]) VALUES (1, N'UserA')
GO
INSERT [dbo].[User] ([ID], [Name]) VALUES (2, N'UserB')
GO
INSERT [dbo].[User] ([ID], [Name]) VALUES (3, N'UserC')
GO
INSERT [dbo].[User] ([ID], [Name]) VALUES (4, N'UserD')
GO
INSERT [dbo].[User] ([ID], [Name]) VALUES (5, N'UserE')
GO
INSERT [dbo].[User] ([ID], [Name]) VALUES (6, N'UserF')
GO
INSERT [dbo].[User] ([ID], [Name]) VALUES (7, N'UserG')
GO
INSERT [dbo].[User] ([ID], [Name]) VALUES (8, N'UserH')
GO
INSERT [dbo].[User] ([ID], [Name]) VALUES (9, N'UserI')
GO
INSERT [dbo].[User] ([ID], [Name]) VALUES (10, N'UserJ')
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (1, 1, 1, 1)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (2, 2, 2, 1)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (3, 3, 3, 1)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (4, 4, 4, 1)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (5, 5, 5, 1)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (6, 6, 6, 1)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (7, 7, 7, 1)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (8, 8, 2, 2)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (9, 9, 3, 2)
GO
INSERT [dbo].[UserJobs] ([ID], [UserID], [GroupID], [EntityID]) VALUES (10, 10, 4, 2)
GO
any solution for that ...
I will repeat that your PARENT_ID values are incorrect. Let us look in detail on the UserI (ID = 9) query to see why.
SELECT T1.ID, UserId, NULL AS PARENT_ID, T1.GroupID, G.EntityLevelID
FROM #UserJobs T1
INNER JOIN #GROUP G ON T1.GROUPID = G.ID
inner join #EntityLevel el on G.EntityLevelID = el.Id
WHERE T1.UserID = 9
This would be the base query when processing UserI, as defined in your data (NOTE: I used temp tables instead of permanent tables to simplify cleanup after the tests) The output of this query fragment looks like this:
ID UserId PARENT_ID GroupID EntityLevelID
9 9 NULL 3 3
No problem so far. So, the recursion portion of your CTE is:
UNION ALL
SELECT T2.ID, T2.UserId, EL.ParentID, T2.GroupID, G.EntityLevelID
FROM #UserJobs T2
INNER JOIN #GROUP G ON T2.GROUPID = G.ID
inner join #EntityLevel el on G.EntityLevelID = el.Id
INNER JOIN MyCTE itms
ON EL.ParentID >= itms.ID -- <<<< PROBLEM!!
As we see above, the value in itms.ID for the first part of this query is [9]. This needs to join to a value in the #EntityLevel.ParentID field. But if you look in the values you are inserting into the #EntityLevel table, your highest ParentID value is a [6]. Since there is no record matching the itms.ID value, no additional records are linked.
A similar problem comes with the UserID = 3 record (Examine the output of the queries to figure out why).
To recap - If you want an item to be linked to another item in a tree, there must be a specific, unique link between the items. You need to ensure that the specific, unique link exists. Note that it does not need to be a single data value, but every time your tree forks, the elements on one branch must be identifiably distinct from the elements on the other branch based on their data values.

SQL UPDATE by groups

Consider following table:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Product](
[ProductID] [int] IDENTITY(1,1) NOT NULL,
[ProductCategory] [int] NOT NULL,
[ProductCategoryGuid] [uniqueidentifier] NULL,
CONSTRAINT [PK_Product] PRIMARY KEY CLUSTERED
(
[ProductID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[Product] ON
GO
INSERT [dbo].[Product] ([ProductID], [ProductCategory], [ProductCategoryGuid]) VALUES (1, 2, NULL)
GO
INSERT [dbo].[Product] ([ProductID], [ProductCategory], [ProductCategoryGuid]) VALUES (2, 2, NULL)
GO
INSERT [dbo].[Product] ([ProductID], [ProductCategory], [ProductCategoryGuid]) VALUES (3, 2, NULL)
GO
INSERT [dbo].[Product] ([ProductID], [ProductCategory], [ProductCategoryGuid]) VALUES (4, 3, NULL)
GO
INSERT [dbo].[Product] ([ProductID], [ProductCategory], [ProductCategoryGuid]) VALUES (5, 4, NULL)
GO
INSERT [dbo].[Product] ([ProductID], [ProductCategory], [ProductCategoryGuid]) VALUES (6, 2, NULL)
GO
INSERT [dbo].[Product] ([ProductID], [ProductCategory], [ProductCategoryGuid]) VALUES (7, 3, NULL)
GO
INSERT [dbo].[Product] ([ProductID], [ProductCategory], [ProductCategoryGuid]) VALUES (8, 4, NULL)
GO
INSERT [dbo].[Product] ([ProductID], [ProductCategory], [ProductCategoryGuid]) VALUES (9, 4, NULL)
GO
SET IDENTITY_INSERT [dbo].[Product] OFF
GO
Data looks like this:
ProductID ProductCategory ProductCategoryGuid
1 2 NULL
2 2 NULL
3 2 NULL
4 3 NULL
5 4 NULL
6 2 NULL
7 3 NULL
8 4 NULL
9 4 NULL
What I would like to achieve is to update [ProductCategoryGuid] column so that all rows with the same value for [ProductCategory] will have the same Guid value in [ProductCategoryGuid] column
To clarify:
Guid values will be generated as a part of the UPDATE query using NEWID() function
Rows with ProductID IN( 1, 2, 3, 6) will have Guid1
Rows with ProductID IN( 4,7) will have Guid2
Rows with ProductID IN( 5,8,9) will have Guid3
I would use following script that use a table variable to store list of distinct categories. The same table variable has a GUID column having as default value NEWID() function. At the end of the script there is an UPDATE statement using table variable as source and dbo.Product table as target:
DECLARE #Results TABLE (
[ProductCategory] [int] NOT NULL,
[ProductCategoryGuid] [uniqueidentifier] NOT NULL DEFAULT (NEWID())
)
INSERT #Results (ProductCategory)
SELECT DISTINCT p.ProductCategory
FROM dbo.Product p
UPDATE p
SET ProductCategoryGuid = r.ProductCategoryGuid
OUTPUT deleted.ProductCategoryGuid, inserted.ProductCategoryGuid
FROM dbo.Product p
INNER JOIN #Results r ON p.ProductCategory = r.ProductCategory
Comment OUTPUT clause if you don't want to see the old and new values.
Update: one statement solution (it requires SQL2012+)
;WITH CteUpdateProduct
AS (
SELECT *, FIRST_VALUE(NewGUID) OVER(PARTITION BY ProductCategory ORDER BY ProductID) AS NewProductCategoryGuid
FROM (
SELECT p.*, NEWID() AS NewGUID
FROM dbo.Product p
) x
)
UPDATE CteUpdateProduct
SET ProductCategoryGuid = NewProductCategoryGuid
OUTPUT inserted.ProductID, inserted.ProductCategory, inserted.ProductCategoryGuid;
WITH productCategories as (
SELECT DISTINCT ProductCategory
FROM product
), productCategoriesWithGuid as (
SELECT ProductCategory, NEWID() ProductCategoryGuid
From productCategories
)
UPDATE product
SET ProductCategoryGuid = pc.ProductCategoryGuid
FROM Product p
JOIN productCategoriesWithGuid pc on p.ProductCategory = pc.ProductCategory
This query gets the distinct ProductCategories,
Creates a GUID for each of them,
And lastly updates the product table with the GUIDs
All in one statement.

Resources