【问题标题】:Can you solve this simple SQL query?你能解决这个简单的 SQL 查询吗?
【发布时间】:2012-02-01 20:33:46
【问题描述】:

假设它是一个销售照相机的网站。这是我的实体(表格):

Camera: A simple camera
Feature: A feature like: 6mp, max resolution 1024x768, 

事情是在相机和功能之间,我有一个多对多的关系,所以我有一个额外的表:

camera -> cameras_features -> feature

所以,查询很简单:

如何获取所有具有功能 1,2 和 3 的相机?

这就像构建一个位图索引。

可用于测试解决方案是否正常的数据

C1 has features 1,2,3
C2 has features 1,2,4
C3 has features 1,2

以下是查询和预期结果:

  • 显示所有具有功能 1,2 和 3 的相机: C1
  • 显示所有具有功能 1,2 和 4 的相机: C2
  • 显示所有具有功能 1 和 2 的相机: C1C2C3

这是我做的(它有效,但它真的很丑,不想使用它):

SELECT * FROM camera c

WHERE c.id IN (    
    (SELECT c.id FROM camera c JOIN cameras_features f ON (c.id=f.camera_id)
    WHERE f.feature_id=1)
        q1 JOIN -- simple intersect
    (SELECT c.id FROM camera c JOIN cameras_features f ON (c.id=f.camera_id)
    WHERE f.feature_id=2)
        q2 JOIN ON (q1.id=q2.id)
)

【问题讨论】:

  • 我很惭愧,这不是作业,但标签还可以。

标签: mysql sql sql-match-all relational-division


【解决方案1】:
SELECT camera.id
FROM camera JOIN camera_features ON camera.id=camera_features.camera_id
GROUP BY camera.id
HAVING sum(camera_features.feature_id IN (1,2,3))=3

3(1,2,3) 中的特征数。并假设(camera_id,feature_id)camera_features 中是唯一的。

【讨论】:

  • 这个假设是可以的。事实上,我在这些列上有一个 UNIQUE。
  • 不,我已经提前考虑过了,谢谢,已解决。 (那是关于分组)。
  • 我假设您可以从具有 id 列表的表中获取其余部分,或者将其塞入此查询中或将其用作子查询。你的尝试表明你有能力:)
  • 有效!真是好东西!关于更改我的表格,我简化了示例;)它有点复杂。你从哪儿弄来的这些东西?我很惊讶。
【解决方案2】:
SELECT DISTINCT Camera.*
FROM Camera c
     INNER JOIN cameras_features fc1 ON c.id = fc1.camera_id AND fc1.feature_id = 1
     INNER JOIN cameras_features fc2 ON c.id = fc2.camera_id AND fc2.feature_id = 2

这里发生的情况是相机将被过滤到具有功能 1 的相机,然后在该组中,相机将被过滤到具有功能 2 的相机

【讨论】:

  • 这行得通!我无法告诉你我现在的情绪。它似乎与我所做的相似,但是使用 JOINS “技巧”,它叫什么?
  • 你可能不需要DISTINCT
  • 另请参阅此问题:How to filter SQL results in a has-many-through relation 以及通过 基准 获得相同结果的数十种其他方法(它们适用于 Postgres,但您会看到多重 JOIN 方法相当快)。
  • 不确定内部连接过滤是否有特定名称,但很高兴我能提供帮助。 @ypercube 不确定我在 MySQL 中是否需要它,但在 MS SQL 中,每个摄像头至少有 2 条记录。
  • 如果(camera_id, feature_id) 在表cameras_features 中是UNIQUE(并且应该是唯一的),那么您不需要distinct
【解决方案3】:

通过将搜索值放入表中,这是最容易概括的...

INSERT INTO search SELECT 1
         UNION ALL SELECT 2
         UNION ALL SELECT 3

SELECT
  camera_features.camera_id
FROM
  camera_features
INNER JOIN
  search
    ON search.id = camera_features.feature_id
GROUP BY
  camera_features.camera_id
HAVING
  COUNT(DISTINCT camera_features.feature_id) = (SELECT COUNT(DISTINCT id) FROM search)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-30
    • 2017-09-09
    • 1970-01-01
    • 2022-10-13
    • 1970-01-01
    • 2021-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多