如果集合匹配,则返回SQL

如果集合匹配,则返回SQL,sql,Sql,我通常知道如何提出详细的问题,但这对我来说很难描述 这是一个非常简单的概念,但我不知道该怎么称呼它 假设用户输入了“materials”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关系的项目表和项目需求表是很容易的。首先

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

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

假设用户输入了“materials”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关系的项目表和项目需求表是很容易的。

首先想到的是扭转这种状况。如果您要查找的所有项目都只能使用手头上的材料制作,这意味着您要查找所有项目,但不包括那些需要材料的项目。这可以用“不存在”来表示

假设您有两个表
Projects
ProjectMaterials
,则查询可能类似于:

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风格不可知的,但是当然,根据您的特定变体的需要对其进行更改

关于表格设计,我推荐一个项目表格和一个多对多的材料表格


我已经使用上面的示例数据创建了此查询和结构的一个示例。

首先想到的是扭转这种情况。如果您要查找的所有项目都只能使用手头上的材料制作,这意味着您要查找所有项目,但不包括那些需要材料的项目。这可以用“不存在”来表示

假设您有两个表
Projects
ProjectMaterials
,则查询可能类似于:

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风格不可知的,但是当然,根据您的特定变体的需要对其进行更改

关于表格设计,我推荐一个项目表格和一个多对多的材料表格


我已经使用上面的示例数据创建了此查询和结构的一个表。

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

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;

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

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;
创建表(如果不存在)`products`(
`id`int无符号非空,
`product`varchar(255)不为空,
`状态“smallint”不为空,
主键(`id`)
)默认字符集=utf8;
在“产品”(`id`、`product`、`status`)值中插入
(1,'A',1),
(2,'B',1),
(3,'C',1),
(4,'D',1),
(5,'E',0),
(6,'F',0),
(7,'G',0),
(8,'R',0);
创建表(如果不存在)`projects`(
`id`int无符号非空,
`project`varchar(255)不为空,
主键(`id`)
)默认字符集=utf8;
在'projects'('id','project`)值中插入
(1,'1'),
(2,'2'),
(3,'3'),
(4,'4');
创建表(如果不存在)`projects\u products`(
`项目_id`int未签名非空,
`product_id`int无符号非空
)默认字符集=utf8;
插入'projects\u products'('project\u id','product\u id')值
(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);
从id不在的项目中选择*(
从项目中选择不同的b.id\u产品a加入项目b
关于a.project_id=b.id
左连接产品c
关于a.product_id=c.id
其中c.状态1)
如果不存在“产品”,则创建表(
`id`int无符号非空,
`product`varchar(255)不为空,
`状态“smallint”不为空,
主键(`id`)
)默认字符集=utf8;
在“产品”(`id`、`product`、`status`)值中插入
(1,'A',1),
(2,'B',1),
(3,'C',1),
(4,'D',1),
(5,'E',0),
(6,'F',0),
(7,'G',0),
(8,'R',0);
创建表(如果不存在)`projects`(
`id`int无符号非空,
`project`varchar(255)不为空,
主键(`id`)
)默认字符集=utf8;
在'projects'('id','project`)值中插入
(1,'1'),
(2,'2'),
(3,'3'),
(4,'4');
创建表(如果不存在)`projects\u products`(
`项目_id`int未签名非空,
`product_id`int无符号非空
)默认字符集=utf8;
插入'projects\u products'('project\u id','product\u id')值
(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);
从id不在的项目中选择*(
从项目中选择不同的b.id\u产品a加入项目b
关于a.project_id=b.id
左连接产品c
关于a.product_id=c.id
其中c.状态1)

您使用的是SQL Server还是MySQL?请正确标记。另外,显示示例数据。我更喜欢MySQL,因为它运行起来更便宜,但如果有必要,我可以运行T-SQL。我知道MySQL的局限性更大。您使用的是SQL Server还是MySQL?请正确标记。另外,显示示例数据。我更喜欢MySQL,因为它运行起来更便宜,但如果有必要,我可以运行T-SQL。我知道MySQL的局限性更大,我喜欢这个答案,它看起来非常可靠。现在,(这不是一个要求)如果我需要一定的数量怎么办?这样做容易吗?我是要让项目材料是n长的(项目1需要A、A、A、B)还是我会有一个数量栏?我会使用数量栏,但如果你处理的是手头数量,那么整个查询就变成了另一个问题。我认为您仍然可以使用类似的方法,但必须检查每种材料的数量以及检查其他材料。谢谢!这不是一个要求的原因是因为大多数项目只需要1,我也可以在前端对它进行排序。另外,如果我在前端把它整理好,我可以展示两套,你有足够的材料,你几乎有足够的材料。我喜欢这个答案,看起来