Sql return 具有特定值的不同行
Sql return distinct rows with specific values
我有一个 table 喜欢
product_id tag_id value
1 1 10
1 2 51
1 3 47
2 1 15
2 2 59
2 3 44
3 1 10
3 2 51
3 3 47
4 1 10
4 2 12
4 3 55
我想创建 returns 个满足所有三个标签 ID 的特定条件的不同产品 ID 的查询。
例如,我想要具有 tag_id 1 = 10 和 tag_id 2 = 51 和 tag_id 3 = 47 的产品 ID。
感谢
或者做 GROUP BY
,使用 HAVING
确保包含所有 3 个不同的 tag_id/value 组合。
SELECT product_id
FROM tablename
WHERE (tag_id = 1 AND value = 10)
OR (tag_id = 2 AND value = 51)
OR (tag_id = 3 AND value = 47)
group by product_id
having count(distinct tag_id) >= 3
或者,进行双重自连接:
select distinct t1.product_id
from
(select product_id from tablename where tag_id = 1 AND value = 10) t1
join
(select product_id from tablename where tag_id = 2 AND value = 51) t2 on t1.product_id = t2.product_id
join
(select product_id from tablename where tag_id = 3 AND value = 47) t3 on t2.product_id = t3.product_id
这通常使用 HAVING
:
SELECT product_id
FROM tablename
WHERE (tag_id = 1 AND value = 10)
OR (tag_id = 2 AND value = 51)
OR (tag_id = 3 AND value = 47)
GROUP BY product_id
HAVING COUNT(*) = 3 -- number of searched combinations
这假定组合tag_id
/value
是唯一的,否则您必须更改计数以添加不同的 COUNT(DISTINCT tag_id)
为了减少错误,我更喜欢在单独的 table 中描述此类条件并加入目标 table:
DECLARE @Products TABLE (product_id int, tag_id int, value int)
INSERT INTO @Products
VALUES
(1, 1, 10),
(1, 2, 51),
(1, 3, 47),
(2, 1, 15),
(2, 2, 59),
(2, 3, 44),
(3, 1, 10),
(3, 2, 51),
(3, 3, 47),
(4, 1, 10),
(4, 2, 12),
(4, 3, 55)
DECLARE @Conditions TABLE (tag_id int, value int)
INSERT INTO @Conditions
VALUES
(1, 10),
(2, 51),
(3, 47)
SELECT p.product_id
FROM @Products p
INNER JOIN @Conditions c ON p.tag_id = c.tag_id AND p.[value] = c.[value]
GROUP BY p.product_id
HAVING COUNT(*) = (SELECT COUNT(*) FROM @Conditions c2)
如果你没有无限可能的组合,我更愿意遵循自然的方法,这也是可维护的(如果条件变得更复杂):
SELECT DISTINCT product_id
FROM dbo.TableName t
WHERE EXISTS
(
SELECT 1 FROM dbo.TableName t1
WHERE t1.product_id = t.product_id
AND t1.tag_id = 1
AND t1.Value = 10
)
AND EXISTS
(
SELECT 1 FROM dbo.TableName t1
WHERE t1.product_id = t.product_id
AND t1.tag_id = 2
AND t1.Value = 51
)
AND EXISTS
(
SELECT 1 FROM dbo.TableName t1
WHERE t1.product_id = t.product_id
AND t1.tag_id = 3
AND t1.Value = 47
)
我有一个 table 喜欢
product_id tag_id value
1 1 10
1 2 51
1 3 47
2 1 15
2 2 59
2 3 44
3 1 10
3 2 51
3 3 47
4 1 10
4 2 12
4 3 55
我想创建 returns 个满足所有三个标签 ID 的特定条件的不同产品 ID 的查询。
例如,我想要具有 tag_id 1 = 10 和 tag_id 2 = 51 和 tag_id 3 = 47 的产品 ID。
感谢
或者做 GROUP BY
,使用 HAVING
确保包含所有 3 个不同的 tag_id/value 组合。
SELECT product_id
FROM tablename
WHERE (tag_id = 1 AND value = 10)
OR (tag_id = 2 AND value = 51)
OR (tag_id = 3 AND value = 47)
group by product_id
having count(distinct tag_id) >= 3
或者,进行双重自连接:
select distinct t1.product_id
from
(select product_id from tablename where tag_id = 1 AND value = 10) t1
join
(select product_id from tablename where tag_id = 2 AND value = 51) t2 on t1.product_id = t2.product_id
join
(select product_id from tablename where tag_id = 3 AND value = 47) t3 on t2.product_id = t3.product_id
这通常使用 HAVING
:
SELECT product_id
FROM tablename
WHERE (tag_id = 1 AND value = 10)
OR (tag_id = 2 AND value = 51)
OR (tag_id = 3 AND value = 47)
GROUP BY product_id
HAVING COUNT(*) = 3 -- number of searched combinations
这假定组合tag_id
/value
是唯一的,否则您必须更改计数以添加不同的 COUNT(DISTINCT tag_id)
为了减少错误,我更喜欢在单独的 table 中描述此类条件并加入目标 table:
DECLARE @Products TABLE (product_id int, tag_id int, value int)
INSERT INTO @Products
VALUES
(1, 1, 10),
(1, 2, 51),
(1, 3, 47),
(2, 1, 15),
(2, 2, 59),
(2, 3, 44),
(3, 1, 10),
(3, 2, 51),
(3, 3, 47),
(4, 1, 10),
(4, 2, 12),
(4, 3, 55)
DECLARE @Conditions TABLE (tag_id int, value int)
INSERT INTO @Conditions
VALUES
(1, 10),
(2, 51),
(3, 47)
SELECT p.product_id
FROM @Products p
INNER JOIN @Conditions c ON p.tag_id = c.tag_id AND p.[value] = c.[value]
GROUP BY p.product_id
HAVING COUNT(*) = (SELECT COUNT(*) FROM @Conditions c2)
如果你没有无限可能的组合,我更愿意遵循自然的方法,这也是可维护的(如果条件变得更复杂):
SELECT DISTINCT product_id
FROM dbo.TableName t
WHERE EXISTS
(
SELECT 1 FROM dbo.TableName t1
WHERE t1.product_id = t.product_id
AND t1.tag_id = 1
AND t1.Value = 10
)
AND EXISTS
(
SELECT 1 FROM dbo.TableName t1
WHERE t1.product_id = t.product_id
AND t1.tag_id = 2
AND t1.Value = 51
)
AND EXISTS
(
SELECT 1 FROM dbo.TableName t1
WHERE t1.product_id = t.product_id
AND t1.tag_id = 3
AND t1.Value = 47
)