用于搜索越来越高级别的SQL冒泡或分层模式

时间:2014-02-06 01:25:39

标签: sql hierarchy

我们有公司,分支机构和用户表/级别。每个级别都有一个与配置表中的配置相关联的可空id。如果配置标识为null,则它应返回更高级别的配置,并且存在与该更高级别关联的非可空标识。如果最高级别没有关联的配置,则不应返回任何内容。另一个复杂因素是配置的IsDeleted值应为0。

这种层次结构有什么好的SQL模式?我确实在网上搜索过这个,但由于我不确定甚至可以调用它,所以它没有产生任何有用的结果。

我在这里尝试了sql小提琴:http://sqlfiddle.com/#!3/f1815/10/0,但我不喜欢我正在使用的模式。模式只是一堆表,每个表都有一个元素,公司是唯一一个指向配置的表。 架构:

-- all ids would be uniqueidentifiers
-- pks and fks are primary and foreign keys that would be.
create table all_user
(
  id int not null, -- pk
  branchid int not null, -- fk
  configID int -- fk
);
create table branch
(
  id int not null, -- pk
  companyID int not null, -- fk
  configID int -- fk
);
create table company
(
  id int not null, -- pk
  configID int -- fk
);

create table config
(
  id int not null, -- pk
  name varchar(36) not null,
  isDeleted bit default(0)
);

insert into config (id, name) values (1, 'firstConfig');
insert into company(id,configID) values (1,1);
insert into branch(id, companyID) values (1, 1);
insert into all_user(id, branchID) values(1, 1);

这是查询:

    declare @UserID int
select @UserID = 1

declare @uconfigID int
declare @bconfigID int
declare @cconfigID int
declare @numConfigs int
    select @numConfigs = 0  -- UPDATE (makes query work)

SELECT @uconfigID = au.configID, @bconfigID = b.configID, @cconfigID = c.configID
from all_user au 
join branch b on au.branchID = b.ID
join company c on b.companyID = c.ID
where au.ID = @UserID

if @uconfigID is not null
BEGIN
    select @numConfigs = count(*) 
    from config
    where id = @uconfigID
    and IsDeleted = 0

    if @numConfigs = 1
    BEGIN
      select *
      from config
      where id = @uconfigID
      and IsDeleted = 0
    END
END

if @numConfigs = 0 and @bconfigID is not null
BEGIN
    select @numConfigs = count(*) 
    from config
    where id = @bconfigID
    and IsDeleted = 0

    if @numConfigs = 1
    BEGIN
      select * 
      from config
      where id = @bconfigID
      and IsDeleted = 0
    END
END

if @numConfigs = 0 and @cconfigID is not null
BEGIN
    select @numConfigs = count(*) 
    from config
    where id = @cconfigID
    and IsDeleted = 0

    if @numConfigs = 1
    BEGIN
      select *
      from config
      where id = @cconfigID
      and IsDeleted = 0
    END
END

另外,我不喜欢我正在使用连接,因为我真的想在第一级将其短路,返回有效(非删除)配置。

有更好的方法吗?也许是递归的?

感谢。

0 个答案:

没有答案