Wrong Result from SQL Server CTE hierarchy [duplicate] - sql-server-2014
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
Related
mysql query on an audit table to get latest row where no delete row exists for each user and type
so im sure this won't tax anyone but new to all this! looking for a way to pull out data from an audit table which gives a view of all the created rows where they have not subsequently been deleted. so by example... CREATE TABLE `test1` ( `tID` INT(11) NULL DEFAULT NULL, `tDate` DATE NULL DEFAULT NULL, `tName` VARCHAR(50) NULL DEFAULT NULL, `tType` VARCHAR(50) NULL DEFAULT NULL, `tAction` VARCHAR(50) NULL DEFAULT NULL ) INSERT INTO `test1` VALUES (1, '2019-02-01', 'Bob', 'a', 'Create'); INSERT INTO `test1` VALUES (2, '2019-02-02', 'Frank', 'a', 'Create'); INSERT INTO `test1` VALUES (3, '2019-02-03', 'Jim', 'b', 'Create'); INSERT INTO `test1` VALUES (4, '2019-02-04', 'Frank', 'a', 'Delete'); INSERT INTO `test1` VALUES (5, '2019-02-05', 'Bob', 'b', 'Create'); INSERT INTO `test1` VALUES (6, '2019-02-06', 'Bob', 'a', 'Delete'); INSERT INTO `test1` VALUES (7, '2019-02-07', 'Bob', 'a', 'Create'); INSERT INTO `test1` VALUES (8, '2019-02-08', 'Frank', 'b', 'Create'); INSERT INTO `test1` VALUES (9, '2019-02-09', 'Bob', 'b', 'Delete'); INSERT INTO `test1` VALUES (10, '2019-02-10', 'Bob', 'b', 'Create'); INSERT INTO `test1` VALUES (11, '2019-02-11', 'kate', 'a', 'Create'); INSERT INTO `test1` VALUES (12, '2019-02-12', 'kate', 'a', 'Delete'); Want the output to be something like... "Bob" "2019-02-07" "a" "Jim" "2019-02-03" "b" "Bob" "2019-02-10" "b" "Frank" "2019-02-08" "b" so i can can get max where create easy enough but how should i exclude the ones that have been deleted after creation? this gets me close... but i need to remove the ones with a later deleted row.. SELECT max(tDate), tname, tType FROM test1 WHERE tAction = 'create' GROUP BY tname, ttype thanks for any help! j.
select * from test1 t1 where t1.tAction <> 'Delete' and not exists ( select * from test1 t2 where t2.tName = t1.tName -- same user and t2.tType = t1.tType -- and same type and t2.tAction = 'Delete' -- deleted and t1.tDate < t2.tDate -- at a later time )
Try using correlated subquery DEMO select * from test1 a where a.taction='Create' and not exists ( select 1 from test1 b where a.tname=b.tname and a.ttype=b.ttype and a.tdate<b.tdate and b.taction<>'Create' ) OUTPUT: tID tDate tName tType tAction 3 2019-02-03 Jim b Create 7 2019-02-07 Bob a Create 8 2019-02-08 Frank b Create 10 2019-02-10 Bob b Create
SELECT tDate, tname, tType FROM test1 WHERE tAction <> 'Delete' I hope this is the query you are looking for. Reference SQL: How to perform string does not equal
How to use the result of a subquery
I have three SQL tables as below: (The "orders" table below is not complete) How to resolve the following question using just one sql query: Select the customers who ordered in 2014 all the products (at least) that the customers named 'Smith' ordered in 2013. Is this possible? I have thought about this: Firstly, find the all the products that the client named "Smith" ordered in 2013. Secondly, find the list of customers who at least have ordered all the above products in 2014. Which brings me to a SQL query like this: SELECT cname, FROM customers NATURAL JOIN orders WHERE YEAR(odate) = '2014' AND "do_something_here" (SELECT DISTINCT pid FROM orders NATURAL JOIN customers WHERE LOWER(cname)='smith' AND YEAR(odate)='2013') as results; in which all the subquery results (the list of products that "Smith" ordered in 2013) should be used to find the clients needed. But I don't know if this is the good approach. Sorry for my English because I am not a native speaker. If you want to test it out on phpMyAdmin, here's the SQL: -- phpMyAdmin SQL Dump -- version 4.7.5 -- https://www.phpmyadmin.net/ -- -- Host: localhost -- Generation Time: Mar 21, 2018 at 02:49 PM -- Server version: 5.7.20 -- PHP Version: 7.1.7 SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET AUTOCOMMIT = 0; START TRANSACTION; SET time_zone = "+00:00"; /*!40101 SET #OLD_CHARACTER_SET_CLIENT=##CHARACTER_SET_CLIENT */; /*!40101 SET #OLD_CHARACTER_SET_RESULTS=##CHARACTER_SET_RESULTS */; /*!40101 SET #OLD_COLLATION_CONNECTION=##COLLATION_CONNECTION */; /*!40101 SET NAMES utf8mb4 */; -- -- Database: `tp1` -- -- -------------------------------------------------------- -- -- Table structure for table `customers` -- CREATE TABLE `customers` ( `cid` int(11) NOT NULL, `cname` varchar(30) NOT NULL, `residence` varchar(50) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -- Dumping data for table `customers` -- INSERT INTO `customers` (`cid`, `cname`, `residence`) VALUES (0, 'didnotorder', 'Great Britain'), (1, 'Jones', 'USA'), (2, 'Blake', NULL), (3, 'Dupond', 'France'), (4, 'Smith', 'Great Britain'), (5, 'Gupta', 'India'), (6, 'Smith', 'France'); -- -------------------------------------------------------- -- -- Table structure for table `orders` -- CREATE TABLE `orders` ( `pid` int(11) NOT NULL, `cid` int(11) NOT NULL, `odate` date NOT NULL, `quantity` int(11) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -- Dumping data for table `orders` -- INSERT INTO `orders` (`pid`, `cid`, `odate`, `quantity`) VALUES (1, 1, '2014-12-12', 2), (1, 4, '2014-11-12', 6), (2, 1, '2014-06-02', 6), (2, 1, '2014-08-20', 6), (2, 1, '2014-12-12', 2), (2, 2, '2010-11-12', 1), (2, 2, '2014-07-21', 3), (2, 3, '2014-10-01', 1), (2, 3, '2014-11-12', 1), (2, 4, '2014-01-07', 1), (2, 4, '2014-02-22', 1), (2, 4, '2014-03-19', 1), (2, 4, '2014-04-07', 1), (2, 4, '2014-05-22', 1), (2, 4, '2014-09-12', 4), (2, 6, '2014-10-01', 1), (3, 1, '2014-12-12', 1), (3, 2, '2013-01-01', 1), (3, 4, '2015-10-12', 1), (3, 4, '2015-11-12', 1), (4, 1, '2014-12-12', 3), (4, 2, '2014-06-11', 2), (4, 5, '2014-10-12', 1), (4, 5, '2014-11-13', 5), (5, 2, '2015-07-21', 3), (6, 2, '2015-07-21', 7), (6, 3, '2014-12-25', 1); -- -------------------------------------------------------- -- -- Table structure for table `products` -- CREATE TABLE `products` ( `pid` int(11) NOT NULL, `pname` varchar(30) NOT NULL, `price` decimal(7,2) NOT NULL, `origin` varchar(20) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -- Dumping data for table `products` -- INSERT INTO `products` (`pid`, `pname`, `price`, `origin`) VALUES (0, 'wasnotordered', '11.00', NULL), (1, 'chocolate', '5.00', 'Belgium'), (2, 'sugar', '0.75', 'India'), (3, 'milk', '0.60', 'France'), (4, 'tea', '10.00', 'India'), (5, 'chocolate', '7.50', 'Switzerland'), (6, 'milk', '1.50', 'France'); -- -- Indexes for dumped tables -- -- -- Indexes for table `customers` -- ALTER TABLE `customers` ADD PRIMARY KEY (`cid`); -- -- Indexes for table `orders` -- ALTER TABLE `orders` ADD PRIMARY KEY (`pid`,`cid`,`odate`), ADD KEY `orders_fk_cid` (`cid`); -- -- Indexes for table `products` -- ALTER TABLE `products` ADD PRIMARY KEY (`pid`); -- -- Constraints for dumped tables -- -- -- Constraints for table `orders` -- ALTER TABLE `orders` ADD CONSTRAINT `orders_fk_cid` FOREIGN KEY (`cid`) REFERENCES `customers` (`cid`), ADD CONSTRAINT `orders_fk_pid` FOREIGN KEY (`pid`) REFERENCES `products` (`pid`); COMMIT; /*!40101 SET CHARACTER_SET_CLIENT=#OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=#OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=#OLD_COLLATION_CONNECTION */;
You can try something like the following. Basically force join the customers with all the products from smith of 2013, then LEFT JOIN with the products each customer bought of 2014. If both counts are equal means that all products from smith of 2013 were bought at least once in 2014, for each customer. SELECT C.cid FROM Customers C CROSS JOIN ( SELECT DISTINCT P.pid FROM Customers C INNER JOIN Orders O ON C.cid = O.cid INNER JOIN Products P ON O.pid = P.pid WHERE C.cname = 'Smith' AND YEAR(O.odate) = 2013) X LEFT JOIN ( SELECT DISTINCT C.cid, P.pid FROM Customers C INNER JOIN Orders O ON C.cid = O.cid INNER JOIN Products P ON O.pid = P.pid WHERE YEAR(O.odate) = 2014) R ON C.cid = R.cid AND X.pid = R.pid GROUP BY C.cid HAVING COUNT(X.pid) = COUNT(R.pid) If you want to see the customers even if there are no products from smith of 2013, you can switch the CROSS JOIN for a FULL JOIN (...) X ON 1 = 1.
You can solve this by finding all the products that each cid has in common with the Smith customers. Then, just check that the count covers all the products: select o2014.cid, count(distinct o2013.pid) as num_products, group_concat(distinct o2013.pid) as products from orders o2013 join orders o2014 on o2013.pid = o2014.pid and year(o2013.odate) = 2013 and year(o2014.odate) = 2014 where o2013.cid = (select c.cid from customers c where c.cname = 'Smith') group by o2014.cid having num_products = (select count(distinct o2013.products) from orders o2013 where o2013.cid = (select c.cid from customers c where c.cname = 'Smith') );
Converting SQL file To CSV
I have dumped a sql table for cities, regions & countries. I have the .sql files in my local machine. I need to convert them to CSV format. So I have a 2 part question. 1): What is the best way to do this? Is any tools I can use? (I have a Mac) 2): I found this site. So I tried with this code: CREATE TABLE IF NOT EXISTS `countries` ( `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `code` varchar(10) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`) ) ENGINE=InnoDB AUTO_INCREMENT=231 DEFAULT CHARSET=latin1; -- Dumping data for table dddblog.countries: ~218 rows (approximately) /*!40000 ALTER TABLE `countries` DISABLE KEYS */; INSERT INTO `countries` (`id`, `name`, `code`) VALUES (1, 'Andorra', 'ad'), (2, 'United Arab Emirates', 'ae'), (3, 'Afghanistan', 'af'), (4, 'Antigua and Barbuda', 'ag'), (5, 'Anguilla', 'ai'), (6, 'Albania', 'al'), (7, 'Armenia', 'am'), (8, 'Netherlands Antilles', 'an'), (9, 'Angola', 'ao'), // Other countries /*!40000 ALTER TABLE `countries` ENABLE KEYS */; And when I click on Convert, I get error: Missing SELECT STATEMENT. Im not familiar with SQL and any help is appreciated!
The message Missing SELECT STATEMENT says it all: You have to add a SELECT statement. Try it with this code - worked for me: CREATE TABLE IF NOT EXISTS `countries` ( `id` smallint(5) NOT NULL , `name` varchar(255) NOT NULL, `code` varchar(10) NOT NULL ); INSERT INTO `countries` (`id`, `name`, `code`) VALUES (1, 'Andorra', 'ad'), (2, 'United Arab Emirates', 'ae'), (3, 'Afghanistan', 'af'), (4, 'Antigua and Barbuda', 'ag'), (5, 'Anguilla', 'ai'), (6, 'Albania', 'al'), (7, 'Armenia', 'am'), (8, 'Netherlands Antilles', 'an'), (9, 'Angola', 'ao') ; SELECT `id`, `name`, `code` FROM `countries`
In on result, get a number of dependency
I have this MySQL DB : MySQL in order to create DB + set of test value : DROP DATABASE IF EXISTS test; CREATE DATABASE test; CREATE TABLE table_status ( Id TINYINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, Status CHAR(27) NOT NULL) ENGINE=INNODB; INSERT INTO table_status (Id, Status) VALUES (1, 'CREATED'), (2, 'UNSURE'), (3, 'RUNNING'), (4, 'BEGIN_ACTION_TRUE'), (5, 'STOPPED_ACTION_TRUE_OK'), (6, 'STOPPED_ACTION_TRUE_NOT_OK'), (7, 'BEGIN_ACTION_FALSE'), (8, 'STOPPED_ACTION_FALSE_OK'), (9, 'STOPPED_ACTION_FALSE_NOT_OK'), (10, 'STOPPED_NOT_OK'), (11, 'STOPPED_OK'), (12, 'CANCEL_REQUESTED'), (13, 'CANCELLED'); CREATE TABLE table_group ( Id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, Status TINYINT UNSIGNED NOT NULL DEFAULT 1, CONSTRAINT fk_group_Status FOREIGN KEY (Status) REFERENCES table_status(Id)) ENGINE=INNODB; CREATE TABLE table_task ( Id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, IdGroup BIGINT UNSIGNED NOT NULL, Status TINYINT UNSIGNED NOT NULL DEFAULT 1, Command TEXT NOT NULL, CONSTRAINT fk_task_IdGroup FOREIGN KEY (IdGroup) REFERENCES table_group(Id) ON DELETE CASCADE, CONSTRAINT fk_task_Status FOREIGN KEY (Status) REFERENCES table_status(Id)) ENGINE=INNODB; CREATE TABLE table_dependency ( IdBeforeTask BIGINT UNSIGNED NOT NULL, IdAfterTask BIGINT UNSIGNED NOT NULL, PRIMARY KEY (IdBeforeTask, IdAfterTask), CONSTRAINT fk_dependency_IdBeforeTask FOREIGN KEY (IdBeforeTask) REFERENCES table_task(Id) ON DELETE CASCADE, CONSTRAINT fk_dependency_IdAfterTask FOREIGN KEY (IdAfterTask) REFERENCES table_task(Id) ON DELETE CASCADE) ENGINE=INNODB; INSERT INTO table_group (Id) VALUES (1), (2), (3), (4); INSERT INTO table_task (IdGroup, Command) VALUES (1, "command_group_1_task_1"), (1, "command_group_1_task_2"), (1, "command_group_1_task_3"), (2, "command_group_2_task_1"), (2, "command_group_2_task_2"), (2, "command_group_2_task_3"), (3, "command_group_3_task_1"), (3, "command_group_3_task_2"), (3, "command_group_3_task_3"), (4, "command_group_4_task_1"), (4, "command_group_4_task_2"), (4, "command_group_4_task_3"); INSERT INTO table_dependency (IdBeforeTask, IdAfterTask) VALUES (1, 2), (2, 3), (4, 5), (5, 6), (7, 8), (8, 9), (10, 11), (11, 12); The data in table_status is fixed to this : INSERT INTO table_status (Id, Status) VALUES (1, 'CREATED') (2, 'UNSURE') (3, 'RUNNING') (4, 'BEGIN_ACTION_TRUE') (5, 'STOPPED_ACTION_TRUE_OK') (6, 'STOPPED_ACTION_TRUE_NOT_OK') (7, 'BEGIN_ACTION_FALSE') (8, 'STOPPED_ACTION_FALSE_OK') (9, 'STOPPED_ACTION_FALSE_NOT_OK') (10, 'STOPPED_NOT_OK') (11, 'STOPPED_OK') (12, 'CANCEL_REQUESTED') (13, 'CANCELLED') The purpose is to have a group containing task, each task can be dependant on another one. What I want to obtain : Group.Id, NB_TASK_TOTAL, NB_TASK_CREATED, NB_TASK_UNSURE But there is a trap : The number of NB_TASK_CREATED is defined as : the number of task with status to CREATED and with no unresolved dependency. An unresolved dependency is defined as a task depend on another wich have a Status != 11 (STOPPED_OK). So if I have this : table_dependency : IdBeforeTask IdAfterTask 1 2 2 3 table_task : Id IdGroup Status Command 1 1 1 command_1 2 1 1 command_2 3 1 1 command_3 I want to have Group.Id, NB_TASK_TOTAL, NB_TASK_CREATED, NB_TASK_UNSURE 1 3 1 0 Here my unsucesful try : SELECT G.Id, (SELECT COUNT(T.Id) FROM table_task as T WHERE T.IdGroup = G.Id), (SELECT COUNT(T.Status = 1) FROM table_task as T WHERE T.IdGroup = G.Id AND T.Id NOT IN (SELECT IdAfterTask from table_dependency as D1 join table_task as T1 on T1.Id=D1.IdBeforeTask WHERE T1.Status!=11)), (SELECT COUNT(T.Status = 2) FROM table_task as T WHERE T.IdGroup = G.Id) FROM table_group as G The problem is I obtain this : Group.Id, NB_TASK_TOTAL, NB_TASK_CREATED, NB_TASK_UNSURE 1 3 1 3 2 3 0 3 (I have 4 group, each group containing 3 task, all the task with Status = 1 (CREATED) and the dependency set in order to have just on "resolved" dependency so i should have Group.Id, NB_TASK_TOTAL, NB_TASK_CREATED, NB_TASK_UNSURE 1 3 1 0 2 3 1 0 instead. I'm a beginner in MySQL, and i'm lost on this one request.
This should do it for you: SELECT T.IdGroup as Group_Id, COUNT(T.IdGroup) as NB_TASK_TOTAL, (SELECT COUNT(Tt.Id) FROM table_task Tt WHERE Tt.IdGroup = T.IdGroup AND Tt.Status = 1) as NB_TASK_CREATED, (SELECT COUNT(Tt.Id) FROM table_task Tt WHERE Tt.IdGroup = T.IdGroup AND Tt.Status = 2 AND Tt.Id NOT IN (SELECT IdAfterTask from table_dependency as D1 join table_task as T1 on T1.Id=D1.IdBeforeTask WHERE T1.Status!=11)) as NB_TASK_UNSURE FROM table_task T GROUP BY T.IdGroup;
search a set of values in other set of values for a row
Hello I am having issues with execution time on a query that searches for users ( from users table ) that are having at least one interest from one specified interests set and a location from a specified locations set. So I have this test DB: CREATE TABLE IF NOT EXISTS `interests` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ; -- -- Dumping data for table `interests` -- INSERT INTO `interests` (`id`, `name`) VALUES (1, 'auto'), (2, 'moto'), (3, 'health'), (4, 'garden'), (5, 'house'), (6, 'music'), (7, 'video'), (8, 'games'), (9, 'it'); -- -------------------------------------------------------- -- -- Table structure for table `locations` -- CREATE TABLE IF NOT EXISTS `locations` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ; -- -- Dumping data for table `locations` -- INSERT INTO `locations` (`id`, `name`) VALUES (1, 'engalnd'), (2, 'austia'), (3, 'germany'), (4, 'france'), (5, 'belgium'), (6, 'italy'), (7, 'russia'), (8, 'poland'), (9, 'norway'), (10, 'romania'); -- -------------------------------------------------------- -- -- Table structure for table `users` -- CREATE TABLE IF NOT EXISTS `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `email` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ; -- -- Dumping data for table `users` -- INSERT INTO `users` (`id`, `email`) VALUES (1, 'email1#test.com'), (2, 'email2#test.com'), (3, 'email3#test.com'), (4, 'email4#test.com'), (5, 'email5#test.com'), (6, 'email6#test.com'), (7, 'email7#test.com'), (8, 'email8#test.com'), (9, 'email9#test.com'), (10, 'email10#test.com'); -- -------------------------------------------------------- -- -- Table structure for table `users_interests` -- CREATE TABLE IF NOT EXISTS `users_interests` ( `user_id` int(11) NOT NULL, `interest_id` int(11) NOT NULL, PRIMARY KEY (`user_id`,`interest_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -- Dumping data for table `users_interests` -- INSERT INTO `users_interests` (`user_id`, `interest_id`) VALUES (1, 1), (1, 2), (2, 5), (2, 7), (2, 8), (3, 1), (4, 1), (4, 5), (4, 6), (4, 7), (4, 8), (5, 1), (5, 2), (5, 8), (6, 3), (6, 7), (6, 8), (7, 7), (7, 9), (8, 5); -- -------------------------------------------------------- -- -- Table structure for table `users_locations` -- CREATE TABLE IF NOT EXISTS `users_locations` ( `user_id` int(11) NOT NULL, `location_id` int(11) NOT NULL, PRIMARY KEY (`user_id`,`location_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -- Dumping data for table `users_locations` -- INSERT INTO `users_locations` (`user_id`, `location_id`) VALUES (2, 5), (2, 7), (2, 8), (3, 1), (4, 1), (4, 5), (4, 6), (4, 7), (4, 8), (5, 1), (5, 2), (5, 8), (6, 3), (6, 7), (6, 8), (7, 7), (7, 9), (8, 5); Is there a better way to query it than this: SELECT email, GROUP_CONCAT( DISTINCT ui.interest_id ) AS interests, GROUP_CONCAT( DISTINCT ul.location_id ) AS locations FROM `users` u LEFT JOIN users_interests ui ON u.id = ui.user_id LEFT JOIN users_locations ul ON u.id = ul.user_id GROUP BY u.id HAVING IF( interests IS NOT NULL , FIND_IN_SET( 2, interests ) OR FIND_IN_SET( 3, interests ) , 1 ) AND IF( locations IS NOT NULL , FIND_IN_SET( 2, locations ) OR FIND_IN_SET( 3, locations ) , 1 ) This is the best solution I found but it still slow on a 500k and 1mil rows in the relational tables ( locations and interests ). Especially when you are matching against a large set of values ( let's say above 50 locations and interests ). So I am trying to achieve the result this query produces, but a bit faster: email interests locations email1#test.com 1,2 [BLOB - 0B] email5#test.com 1,2,8 1,2,8 email6#test.com 3,7,8 3,7,8 email9#test.com [BLOB - 0B] [BLOB - 0B] email10#test.com [BLOB - 0B] [BLOB - 0B] I also tried to join against an SELECT UNION table - for the matching set - but it was even slower. Like this: SELECT * FROM `users` u LEFT JOIN users_interests ui ON u.id = ui.user_id LEFT JOIN users_locations ul ON u.id = ul.user_id LEFT JOIN (SELECT 2 as interest UNION SELECT 3 as interest) as `is` ON ui.interest_id = is.interest LEFT JOIN (SELECT 2 as location UNION SELECT 3 as location ) as `ls` ON ul.location_id = ls.location WHERE IF(ui.user_id IS NOT NULL, `is`.interest IS NOT NULL,1) AND IF(ul.user_id IS NOT NULL, ls.location IS NOT NULL,1) GROUP BY u.id I am using this for a basic targeting system. I would appreciate very much, any suggestion! Thank you!
you have IS is reserved word for mysql and also your group by can slow your query but i dont see any meaning to use group by u.id here since the u.id is already unique id. look demo try use backticks around it. SELECT * FROM `users` u LEFT JOIN users_interests ui ON u.id = ui.user_id LEFT JOIN users_locations ul ON u.id = ul.user_id LEFT JOIN (SELECT 2 as interest UNION SELECT 3 as interest) as `is` ON ui.interest_id = `is`.interest LEFT JOIN (SELECT 2 as location UNION SELECT 3 as location ) as `ls` ON ul.location_id = `ls`.location WHERE IF(ui.user_id IS NOT NULL, `is`.interest IS NOT NULL,1) AND IF(ul.user_id IS NOT NULL, `ls`.location IS NOT NULL,1)