从同一个表中选择子记录

时间:2015-07-27 14:00:44

标签: mysql

我有一个“公司”表,它与表“companycategorylink”有关系,该表与“类别”有关系。我有一个查询,我可以根据公司ID选择所有公司。我的类别表中有一个字段,用于标识父类别,因此我可以使用嵌套类别。我只需要改变我的设计,你现在可以“合并”类别。您可以通过在父类别中设置标记将类别标记为“合并”。基本上这样多个类别显示为一个。问题是,我现在还必须选择链接到与父类别相关联的所有合并类别的所有公司,同时它还可以用于没有合并的类别。它不应该破坏非合并的类别。我不知道我会怎么做。因为我需要发布我目前拥有的代码片段,所以它是:

SELECT company.Name AS CompanyName, company.Description, company.Logo, company.CompanyID, company.Telephone, company.Fax, company.Address, company.City, category.Name, category.CategoryID
FROM company
JOIN categorycompanylink ON categorycompanylink.CompanyID = company.CompanyID
JOIN category ON categorycompanylink.CategoryID = category.CategoryID
JOIN company ON category.Combined = 1 
WHERE category.CategoryID =19
但是,这显然是不完整的,但我完全陷入困境。我该怎么做呢?

这是我的类别表: enter image description here

这是我的公司表 enter image description here

任何帮助都是适当的。我不知道如何继续

1 个答案:

答案 0 :(得分:0)

这可能是你想要的也可能不是(请重写你的问题)SQL Fiddle demo

最终查询:

select * from (
  select node_category.* from category as parent_category
    join category as node_category on node_category.lft between parent_category.lft + 1 and parent_category.rgt - 1
    where parent_category.id = 2
        and node_category.merged
  union
    select * from category where id = 2) as category
  left join company_has_category on category.id = category_id
  left join company              on company_id = company.id;

表格:

create table company (
  id int primary key auto_increment,
  name varchar(20) not null
);
insert into company values (default, 'company 1'), (default, 'company 2'), (default, 'company 3');

create table category (
  id int primary key auto_increment,
  name varchar(20) not null,
  merged bool not null default false,
  lft int not null,
  rgt int not null
);
insert into category values 
 (1,  'Electronics',          false, 1,20),
 (2,  'Televisions',          false,  2,9),
 (3,  'Tube',                 false, 3,4),
 (4,  'LCD',                  true, 5,6),
 (5,  'Plasma',               true, 7,8),
 (6,  'Portable Electronics', false, 10,19),
 (7,  'MP3 PLAYERS',          false, 11,14),
 (8,  'Flash',                false, 12,13),
 (9,  'CD Players',           false, 15,16),
 (10, '2 Way Radios',         false, 17,18)
;

create table company_has_category (
  company_id int,
  category_id int,
  constraint foreign key (company_id) references company (id),
  constraint foreign key (category_id) references category (id)
);

insert into company_has_category values (1, 1), (2, 1), (1, 2), (3, 2);

一些查询可帮助您了解其工作原理:

-- the data
select company.*, company_has_category.*, category.* from company_has_category
  left join company on company.id = company_id
  right join category on category_id = category.id;

# id, name,        company_id, category_id, id, name,                merged, lft, rgt
1,    'company 1', 1,          1,           1,  'Electronics',       0,      1,   20
2,    'company 2', 2,          1,           1,  'Electronics',       0,      1,   20
1,    'company 1', 1,          2,           2,  'Televisions',       0,      2,   9
3,    'company 3', 3,          2,           2,  'Televisions',       0,      2,   9
NULL, NULL,        NULL,       NULL,        3,  'Tube',              0,      3,   4
NULL, NULL,        NULL,       NULL,        4,  'LCD',               1,      5,   6
NULL, NULL,        NULL,       NULL,        5,  'Plasma',            1,      7,   8
NULL, NULL,        NULL,       NULL,        6,  'Port. Electronics', 0,      10,  19
NULL, NULL,        NULL,       NULL,        7,  'MP3 PLAYERS',       0,      11,  14
NULL, NULL,        NULL,       NULL,        8,  'Flash',             0,      12,  13
NULL, NULL,        NULL,       NULL,        9,  'CD Players',        0,      15,  16
NULL, NULL,        NULL,       NULL,        10, '2 Way Radios',      0,      17,  18


-- the children of category 2 (without the parent) which have their merged flag set
select * from category as parent_category
  join category as node_category on node_category.lft between parent_category.lft + 1 and parent_category.rgt - 1
  where parent_category.id = 2
        and node_category.merged
;

-- the children with merged set plus the parent
-- (if the parent has her merged flag always set, the union can be dropped)
select node_category.* from category as parent_category
  join category as node_category on node_category.lft between parent_category.lft + 1 and parent_category.rgt - 1
  where parent_category.id = 2
        and node_category.merged
union
  select * from category where id = 2;