繁体   English   中英

SQL-返回与所有输入匹配的记录

[英]SQL - return records that match ALL inputs

我具有以下结构,其中包含产品,值/描述符,这些值的类别以及一些桥接表。 类别和值之间存在一个过渡表,因为类别可以具有多个值,并且值可以属于多个类别。 CategoriesValues本质上是可以分配给产品的标签。 然后有一个产品表,该表具有一个产品<-> categoryvalues桥表,称为ProductsCategoryValue。 希望这是有道理的。

该应用程序需要发送一个标签列表(categoryvalueIDs),然后我只需要返回与所有CategoryValueIDs匹配的产品。 在下面的示例中,我发送了标签(categoryvalueID)4、8、20和71。我有一些带有标签4的产品,有几个带有标签20的产品。我有一个具有所有四个标签的产品(4、8 ,20,71)。 我只想退货那一种产品。 但是下面的代码获得了匹配任何产品的产品。

此代码返回与任何值匹配的产品。 我只想返回与所有值匹配的产品。 我觉得我缺少一些简单的东西。 有人可以帮忙吗?

我愿意(a)更改表的布局和模型,或者(b)针对当前结构的任何查询帮助。

顺便说一句,这是在MySQL中。

SELECT  p.ProductID,
    p.ProductName,
    p.ProductDescription,
    pv.CategoryValueID,
    cat.CategoryName,
    v.ValueString
FROM    Products cp
INNER JOIN ProductsCategoriesValues pcv
ON  p.ProductID = pcv.ProductID
INNER JOIN CategoriesValues cv
ON  pcv.CategoryValueID = cv.CategoryValueID
INNER JOIN Categories cat
ON  cat.CategoryID = cv.CategoryID
INNER JOIN `Values` v
ON  v.ValueID = cv.ValueID
WHERE   pcv.CategoryValueID IN (4,8,20,71)
ORDER BY ProductID, CategoryValueID

结构体

CREATE TABLE `Products` (
  `ProductID` int(11) NOT NULL AUTO_INCREMENT,
  `ProductName` varchar(50) NOT NULL,
  `ProductDescription` varchar(400) NOT NULL,
  `Price` decimal(19,4) NOT NULL,
  PRIMARY KEY (`ProductID`)
) 

CREATE TABLE `Categories` (
  `CategoryID` int(11) NOT NULL AUTO_INCREMENT,
  `CategoryName` varchar(100) NOT NULL,
  `CategoryDescription` varchar(500) DEFAULT NULL,
  `CategoryUIOrder` int(11) unsigned NOT NULL,
  PRIMARY KEY (`CategoryID`)
) 


CREATE TABLE `Values` (
  `ValueID` int(11) NOT NULL AUTO_INCREMENT,
  `ValueString` varchar(500) NOT NULL,
  PRIMARY KEY (`ValueID`)
) 


CREATE TABLE `CategoriesValues` (
  `CategoryValueID` int(11) NOT NULL AUTO_INCREMENT,
  `CategoryID` int(11) NOT NULL,
  `ValueID` int(11) NOT NULL,
  PRIMARY KEY (`CategoryValueID`),
  KEY `FK_Values__Categories_idx` (`ValueID`),
  KEY `FK_Categories_Values_idx` (`CategoryID`),
  CONSTRAINT `FK_Categories_Values` FOREIGN KEY (`CategoryID`) REFERENCES `Categories` (`CategoryID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `FK_Values_Categories` FOREIGN KEY (`ValueID`) REFERENCES `Values` (`ValueID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) 


CREATE TABLE `ProductsCategoriesValues` (
  `ProductID` int(11) NOT NULL,
  `CategoryValueID` int(11) NOT NULL,
  PRIMARY KEY (`ProductID`,`CategoryValueID`),
  KEY `FK_ProductsCategoryValues_Products` (`ProductID`),
  KEY `FK_ProductsCategoryValues_CategoryValue` (`CategoryValueID`),
  CONSTRAINT `FK_ProductsCategoryValues_CategoryValue` FOREIGN KEY (`CategoryValueID`) REFERENCES `CategoriesValues` (`CategoryValueID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `FK_ProductsCategoryValues_Concepts` FOREIGN KEY (`ProductID`) REFERENCES `Products` (`ProductID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) 

编辑-----添加样本数据。

Products table
ProductsID, ProdName
1, Name1
2, Name2
3, Name3

Categories table
CategoryID, CategoryDescription
1, Cat1
2, Cat2
3, Cat3

Values table
ValueID, ValueDescription
1, Red
2, Blue
3, Green
4, Large
5, Small
6, New
7, Used
8, Tech
9, Toy
10, Fun

CategoriesValues Table
CategoryValueID, CategoryID, ValueID
1, 1, 1
…
4, 1, 1
…
8, 1, 3
…
20, 2, 9
…
71, 2, 10


ProductsCategoriesValues table
ProductID, CategoryValueID
1, 4
1, 8
1, 20
1, 71
2, 4
2, 8
3, 8
3, 20
4, 71

Desired output
1, 4
1, 8
1, 20
1, 71

这是在ProductsCategoriesValues表中查找与所有四个类别值匹配的产品ID的方法:

select productid
from productscategoriesvalues
where categoryvalueid in (4, 8, 20, 71)
group by productid
having count(*) = 4;

当您想在查询中显示带有类别及其值的产品时,请保持查询不变,但是将其添加到其WHERE子句中:

AND p.ProductID IN
(
  select productid
  from productscategoriesvalues
  where categoryvalueid in (4, 8, 20, 71)
  group by productid
  having count(*) = 4
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM