![](/img/trans.png)
[英]SQL — return groups of records where one of the fields does not match amongst all records in the group
[英]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.