连接两个父表,所有子项都需要匹配

发布于 2024-12-10 10:56:16 字数 2201 浏览 0 评论 0原文

我有 2 个表,它们共享一个通用的“类型”表 类型表如下:

CREATE TABLE [ModifierType](
[ModifierTypeID] [int] NOT NULL,
[Code] [varchar](10) NOT NULL,
[Name] [varchar](50) NOT NULL,)

CREATE TABLE [UserRequest](
[UserRequestID] [int] NOT NULL,
[Name] [varchar](50) NOT NULL,)

CREATE TABLE [Matrix](
[MatrixID] [int] NOT NULL,
[Name] [varchar](50) NOT NULL,)

CREATE TABLE [UserRequestModifier](
[UserRequestModifierID] [int] NOT NULL,
[UserRequestID] [int] NOT NULL,
[ModifierTypeID] [int] NOT NULL,
[Value] [varchar](50) NOT NULL,)

CREATE TABLE [MatrixModifier](
[MatrixModifierID] [int] NOT NULL,
[MatrixID] [int] NOT NULL,
[ModifierTypeID] [int] NOT NULL,
[Value] [varchar](50) NOT NULL,)

其他是UserRequestModifier表和“MatrixModifier”表,其中包含用于确定应该提供请求的访问的规则。在这种情况下,矩阵仅指一组授予特定应用程序或组访问权限的规则。这两个表各自有一个 ModifierTypeID(它将链接这两个表)和一个用于查找匹配项的值字段。

但是,每个 UserRequest/Matrix(修饰符表的父级)都可以有多个修饰符记录。

我需要做的是找到 UserRequestModifiers 满足所有 MatrixModifier 要求的所有 Matrix 记录。基本上,我想忽略任何具有 1 个与任何 UserRequestModifier 值都不匹配的修饰符值的 MatrixID。

到目前为止,我有一个查询可以做到这一点,但对我来说似乎有点倒退,因为我必须首先找到 UserRequestModifiers 不满足子选择要求的所有 MatrixID。然后获取不在这些结果中的记录,如下所示:

SELECT 
    UR.[UserRequestModifierID]
    ,UR.[ModifierTypeID]        
    ,UR.[Value] AS [URValue]
    ,MM.[Value] AS [MMValue]
    ,MM.[MatrixModifierID]
    ,MM.[MatrixID]
    ,MM.[ModifierTypeID]        
    ,M.[MatrixID]       
FROM
    AMP.[UserRequestModifier] AS UR
LEFT OUTER JOIN AMP.[MatrixModifier] AS MM
    ON (MM.[ModifierTypeID] = UR.[ModifierTypeID])
LEFT OUTER JOIN AMP.[Matrix] AS M
WHERE
    UR.[UserRequestID] = @UserRequestID
    AND M.[MatrixID] IS NOT NULL
    AND M.[MatrixID] NOT IN
        (SELECT
            DISTINCT MM.[MatrixID]      
        FROM
            AMP.[UserRequestModifier] AS UR
        LEFT OUTER JOIN AMP.[MatrixModifier] AS MM
            ON (MM.[ModifierTypeID] = UR.[ModifierTypeID])
        WHERE
            UR.[UserRequestID] = @UserRequestID
            AND (CASE WHEN LTRIM(RTRIM(MM.[Value])) = LTRIM(RTRIM(UR.[Value])) THEN 1 ELSE 0 END) = 0
            AND MM.[MatrixID] IS NOT NULL)
ORDER BY M.[MatrixID], MM.[ModifierTypeID]

我知道这有点难以理解,但我希望有人能指出我遗漏的明显内容。

I have 2 tables which share a common table of "types"
The type table is as follows:

CREATE TABLE [ModifierType](
[ModifierTypeID] [int] NOT NULL,
[Code] [varchar](10) NOT NULL,
[Name] [varchar](50) NOT NULL,)

CREATE TABLE [UserRequest](
[UserRequestID] [int] NOT NULL,
[Name] [varchar](50) NOT NULL,)

CREATE TABLE [Matrix](
[MatrixID] [int] NOT NULL,
[Name] [varchar](50) NOT NULL,)

CREATE TABLE [UserRequestModifier](
[UserRequestModifierID] [int] NOT NULL,
[UserRequestID] [int] NOT NULL,
[ModifierTypeID] [int] NOT NULL,
[Value] [varchar](50) NOT NULL,)

CREATE TABLE [MatrixModifier](
[MatrixModifierID] [int] NOT NULL,
[MatrixID] [int] NOT NULL,
[ModifierTypeID] [int] NOT NULL,
[Value] [varchar](50) NOT NULL,)

The others are a UserRequestModifier table, and a "MatrixModifier" table which contains rules for determining access a request should be provisioned. Matrix in this case just refers to a set of rules that will grant access to a specific application or group. These two tables each have a ModifierTypeID which will link the two and a value field that will be used for finding matches.

However, each UserRequest/Matrix (parents to the modifier tables) can each have multiple modifier records.

What I need to do, is find all the Matrix records for which the UserRequestModifiers meets all the MatrixModifier requirements. Basically, I want to ignore any MatrixIDs that have even 1 modifier value that does not match ANY of the UserRequestModifier values.

So far I have a query that will do it, but it seems a bit backwards to me, because I'm having to first find all the MatrixIDs that the UserRequestModifiers do not meet the requirements in a subselect. Then getting the records that are NOT IN those results as follows:

SELECT 
    UR.[UserRequestModifierID]
    ,UR.[ModifierTypeID]        
    ,UR.[Value] AS [URValue]
    ,MM.[Value] AS [MMValue]
    ,MM.[MatrixModifierID]
    ,MM.[MatrixID]
    ,MM.[ModifierTypeID]        
    ,M.[MatrixID]       
FROM
    AMP.[UserRequestModifier] AS UR
LEFT OUTER JOIN AMP.[MatrixModifier] AS MM
    ON (MM.[ModifierTypeID] = UR.[ModifierTypeID])
LEFT OUTER JOIN AMP.[Matrix] AS M
WHERE
    UR.[UserRequestID] = @UserRequestID
    AND M.[MatrixID] IS NOT NULL
    AND M.[MatrixID] NOT IN
        (SELECT
            DISTINCT MM.[MatrixID]      
        FROM
            AMP.[UserRequestModifier] AS UR
        LEFT OUTER JOIN AMP.[MatrixModifier] AS MM
            ON (MM.[ModifierTypeID] = UR.[ModifierTypeID])
        WHERE
            UR.[UserRequestID] = @UserRequestID
            AND (CASE WHEN LTRIM(RTRIM(MM.[Value])) = LTRIM(RTRIM(UR.[Value])) THEN 1 ELSE 0 END) = 0
            AND MM.[MatrixID] IS NOT NULL)
ORDER BY M.[MatrixID], MM.[ModifierTypeID]

I know this is a bit hard to follow, but I'm hoping someone can point out something obvious I'm missing.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

撧情箌佬 2024-12-17 10:56:16

正如马丁·史密斯指出的那样,这是一个关系划分问题。我认为解决这个问题的一种方法是:

SELECT
    M.*
FROM
    Matrix AS M
  LEFT JOIN
    MatrixModifier AS MM
        ON MM.MatrixID = M.MatrixID
  LEFT JOIN 
    UserRequestModifier AS URM
        ON URM.ModifierTypeID = MM.ModifierTypeID
GROUP BY
    M.MatrixID
HAVING
    COUNT(DISTINCT MM.ModifierTypeID) = COUNT(DISTINCT URM.ModifierTypeID)

It's a relational division problem, as Martin Smith pointed. One way to solve it, I think, is this:

SELECT
    M.*
FROM
    Matrix AS M
  LEFT JOIN
    MatrixModifier AS MM
        ON MM.MatrixID = M.MatrixID
  LEFT JOIN 
    UserRequestModifier AS URM
        ON URM.ModifierTypeID = MM.ModifierTypeID
GROUP BY
    M.MatrixID
HAVING
    COUNT(DISTINCT MM.ModifierTypeID) = COUNT(DISTINCT URM.ModifierTypeID)
别靠近我心 2024-12-17 10:56:16

对于 MS SQL Server:

-- ====================
-- sample data
-- ====================
DECLARE @ModifierType TABLE (
[ModifierTypeID] [int] NOT NULL,
[Code] [varchar](10) NOT NULL,
[Name] [varchar](50) NOT NULL)

DECLARE @UserRequest TABLE (
[UserRequestID] [int] NOT NULL,
[Name] [varchar](50) NOT NULL)

DECLARE @Matrix TABLE (
[MatrixID] [int] NOT NULL,
[Name] [varchar](50) NOT NULL)

DECLARE @UserRequestModifier TABLE (
[UserRequestModifierID] [int] NOT NULL,
[UserRequestID] [int] NOT NULL,
[ModifierTypeID] [int] NOT NULL,
[Value] [varchar](50) NOT NULL)

DECLARE @MatrixModifier TABLE (
[MatrixModifierID] [int] NOT NULL,
[MatrixID] [int] NOT NULL,
[ModifierTypeID] [int] NOT NULL,
[Value] [varchar](50) NOT NULL)

insert into @modifiertype
select 1, '1', 'modname1'
union all
select 2, '2', 'modname2'
union all
select 3, '3', 'modname3'
union all
select 4, '4', 'modname4'
union all
select 5, '5', 'modname5'
union all
select 6, '6', 'modname6'

insert into @userrequest
select 1, 'ureq1'
union all
select 2, 'ureq2'
union all
select 3, 'ureq3'
union all
select 4, 'ureq4'

insert into @matrix
select 1, 'm1'
union all
select 2, 'm2'
union all
select 3, 'm3'
union all
select 4, 'm4'


insert into @userrequestmodifier
select 1, 1, 1, 'val1'
union all
select 2, 1, 2, 'val2'
union all
select 3, 1, 3, 'val3'
union all
select 4, 1, 4, 'val4'
union all
select 5, 2, 5, 'val5'
union all
select 6, 1, 5, 'val5'
union all
select 7, 1, 6, 'val6'
union all
select 8, 1, 6, 'val6'




insert into @matrixmodifier
select 1, 1, 1, 'val1'
union all
select 2, 2, 2, 'val2'
union all
select 3, 3, 3, 'val'
union all
select 4, 2, 4, 'val4'
union all
select 5, 2, 5, 'val5'
union all
select 6, 3, 4, 'val4'
union all
select 7, 13, 4, 'val4'

declare @UserRequestID int
set @UserRequestID = 1


-- ====================
-- solution
-- ====================
select
    userrequestmodifierid,
    modifiertypeid,
    urvalue,
    mmvalue,
    matrixmodifierid,
    mmmatrixid,
    mmatrixid
from
(
    select 
        urm.userrequestmodifierid,
        urm.modifiertypeid,
        urvalue = urm.value,
        mmvalue = mm.value,
        mm.matrixmodifierid,
        mmmatrixid = mm.matrixid,
        mmatrixid = m.matrixid,
        f = max(case when urm.value != mm.value then 1 end) over (partition by mm.matrixid)
    from @userrequestmodifier urm
    left join @matrixmodifier mm on
        urm.modifiertypeid = mm.modifiertypeid
    left join @matrix m on
        m.matrixid = mm.matrixid
    where urm.userrequestid = @userrequestid
) t
where f is null or mmatrixid is null

For MS SQL Server:

-- ====================
-- sample data
-- ====================
DECLARE @ModifierType TABLE (
[ModifierTypeID] [int] NOT NULL,
[Code] [varchar](10) NOT NULL,
[Name] [varchar](50) NOT NULL)

DECLARE @UserRequest TABLE (
[UserRequestID] [int] NOT NULL,
[Name] [varchar](50) NOT NULL)

DECLARE @Matrix TABLE (
[MatrixID] [int] NOT NULL,
[Name] [varchar](50) NOT NULL)

DECLARE @UserRequestModifier TABLE (
[UserRequestModifierID] [int] NOT NULL,
[UserRequestID] [int] NOT NULL,
[ModifierTypeID] [int] NOT NULL,
[Value] [varchar](50) NOT NULL)

DECLARE @MatrixModifier TABLE (
[MatrixModifierID] [int] NOT NULL,
[MatrixID] [int] NOT NULL,
[ModifierTypeID] [int] NOT NULL,
[Value] [varchar](50) NOT NULL)

insert into @modifiertype
select 1, '1', 'modname1'
union all
select 2, '2', 'modname2'
union all
select 3, '3', 'modname3'
union all
select 4, '4', 'modname4'
union all
select 5, '5', 'modname5'
union all
select 6, '6', 'modname6'

insert into @userrequest
select 1, 'ureq1'
union all
select 2, 'ureq2'
union all
select 3, 'ureq3'
union all
select 4, 'ureq4'

insert into @matrix
select 1, 'm1'
union all
select 2, 'm2'
union all
select 3, 'm3'
union all
select 4, 'm4'


insert into @userrequestmodifier
select 1, 1, 1, 'val1'
union all
select 2, 1, 2, 'val2'
union all
select 3, 1, 3, 'val3'
union all
select 4, 1, 4, 'val4'
union all
select 5, 2, 5, 'val5'
union all
select 6, 1, 5, 'val5'
union all
select 7, 1, 6, 'val6'
union all
select 8, 1, 6, 'val6'




insert into @matrixmodifier
select 1, 1, 1, 'val1'
union all
select 2, 2, 2, 'val2'
union all
select 3, 3, 3, 'val'
union all
select 4, 2, 4, 'val4'
union all
select 5, 2, 5, 'val5'
union all
select 6, 3, 4, 'val4'
union all
select 7, 13, 4, 'val4'

declare @UserRequestID int
set @UserRequestID = 1


-- ====================
-- solution
-- ====================
select
    userrequestmodifierid,
    modifiertypeid,
    urvalue,
    mmvalue,
    matrixmodifierid,
    mmmatrixid,
    mmatrixid
from
(
    select 
        urm.userrequestmodifierid,
        urm.modifiertypeid,
        urvalue = urm.value,
        mmvalue = mm.value,
        mm.matrixmodifierid,
        mmmatrixid = mm.matrixid,
        mmatrixid = m.matrixid,
        f = max(case when urm.value != mm.value then 1 end) over (partition by mm.matrixid)
    from @userrequestmodifier urm
    left join @matrixmodifier mm on
        urm.modifiertypeid = mm.modifiertypeid
    left join @matrix m on
        m.matrixid = mm.matrixid
    where urm.userrequestid = @userrequestid
) t
where f is null or mmatrixid is null
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文