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

时间:2017-11-08 03:28:50

标签: mysql sql

我有下面的结构,我们有产品,值/描述符,这些值的类别和一些桥表。一个桥牌表在Categories&值,因为类别可以有许多值,并且值可以属于多个类别。 CategoriesValues本质上是可以分配给产品的标签。然后有一个product表,它有一个产品< - > categoryvalues桥表,名为ProductsCategoryValue。希望这是有道理的。

应用程序需要发送标签列表(categoryvalueIDs),然后我需要只返回与所有CategoryValueID匹配的产品。在下面的示例中,我发送了标签(categoryvalueID)4,8,20和71.我有一些产品有标签4,少数有标签20.我有一个产品有四个标签(4,8) ,20,71)。我只想退回那一件产品。但是下面的代码会得到与之匹配的产品。

此代码返回与任何值匹配的产品。我只想返回与所有值匹配的产品。我觉得我错过了一些简单的事情。有人可以帮忙吗?

我愿意接受(a)更改表格布局&模型或(b)对当前结构的任何查询帮助。

BTW这是在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

1 个答案:

答案 0 :(得分:1)

这是在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
)