如果设置匹配,则返回SQL

时间:2017-09-05 01:14:24

标签: sql

我通常知道如何提出详细的问题,但我很难描述。

这是一个非常简单的概念,但我不知道该怎么称呼它。

让我们假设用户放了“材料”。 " A,B,C,D"。我想退回所有项目'可以使用这些材料制作。让我们说我有项目1,2,3和4需要[A,C],[D,F,G],[A,B,C,R,Q]和[A,C] ,D]。我想要返回1和4,因为可以制作,而2和3不能,所以不应该返回。

这是清楚的吗?我不知道该怎么称呼它。还有关于表格设置的任何建议吗?我有一个项目表和项目需求表与1-many关系很容易。

3 个答案:

答案 0 :(得分:1)

首先想到的是扭转局面。如果您正在寻找只能使用现有材料制作的所有项目,这意味着您正在寻找除了那些需要您没有材料的项目之外的所有项目。这可以用 NOT EXISTS 来表达。

假设您有两分钟ProjectsProjectMaterials,则查询可能如下所示:

select *
from Projects p
where not exists (
    select 1
    from ProjectMaterials pm
    where pm.ProjectId = p.Id
    and pm.MaterialId not in ('A', 'B', 'C', 'D')
)

此查询应该与SQL风格无关,但当然会根据您的特定变体进行更改。

关于表格设计,我建议一个项目表和一个材料表,加入多对多。

我使用上面的示例数据创建了SQL Fiddle demo此查询和结构。

答案 1 :(得分:1)

如果我假设您有一个名为ProjectMaterials的表(如@lc。那样),那么您可以使用条件聚合:

select pm.projectid
from ProjectMaterials pm
group by pm.projectid
having sum(case when pm.materialid not in ('A', 'B', 'C', 'D') then 1 else 0 end) = 0;

答案 2 :(得分:0)

CREATE TABLE IF NOT EXISTS `products` (
  `id` int unsigned NOT NULL,
  `product` varchar(255) NOT NULL,
  `status` smallint NOT NULL,
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;

INSERT INTO `products` (`id`, `product`, `status`) VALUES
  (1,'A',1),
  (2,'B',1),
  (3,'C',1),
  (4,'D',1),
  (5,'E',0),
  (6,'F',0),
  (7,'G',0),
  (8,'R',0);

CREATE TABLE IF NOT EXISTS `projects` (
  `id` int unsigned NOT NULL,
  `project` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;

INSERT INTO `projects` (`id`, `project`) VALUES
  (1,'1'),
  (2,'2'),
  (3,'3'),
  (4,'4');



CREATE TABLE IF NOT EXISTS `projects_products` (
  `project_id` int unsigned NOT NULL,
  `product_id` int unsigned NOT NULL
) DEFAULT CHARSET=utf8;

INSERT INTO `projects_products` (`project_id`, `product_id`) VALUES
  (1,1),
  (1,3),
  (2,2),
  (2,6),
  (2,7),
  (3,1),
  (3,2),
  (3,3),
  (3,8),
  (3,9),
  (4,1),
  (4,3),
  (4,4);


select * from project where id not in (
select distinct b.id from projects_products a join projects b
on a.project_id = b.id
left join products c
on a.product_id = c.id
where c.status <> 1)