【问题标题】:How to get an ID associated with at least all contents?如何获取至少与所有内容相关联的 ID?
【发布时间】:2015-08-21 10:05:43
【问题描述】:

假设我们有数据库:

-----------
| A -|- B |
|----|----|
| 1  |  1 |
| 1  |  2 |
| 2  |  1 |
-----------

其中AB 是主键。假设我们要获取所有As中包含B中1和2的元素。

SELECT A FROM Table WHERE B = 1 AND B = 2;

上述失败是因为它永远不会成立,因为查询仅针对单个记录。

SELECT A FROM Table WHERE B = 1 OR B = 2;

有效但错误地包含主键值 2,它仅映射到 B 中的 1,而不是 B 中的 1 和 2。

【问题讨论】:

  • A 可能是外键?
  • 修复了这个问题。 A 和 B 现在是主键。
  • 您的意思是 (A, B) 现在是唯一的主键...(从问题中删除 pk 部分,您将不必再回答任何有关它的问题!)跨度>

标签: sql


【解决方案1】:

GROUP BY解决方案,返回所有在(1,2)中具有超过1个不同b值的a:

select a from table
where b in (1,2)
group by a
having count(distinct b) > 1

或者,JOIN 解决方案:

select distinct a
from (select a from table where b = 1) t1
join (select a from table where b = 2) t2
  on t1.a = t2.a

INTERSECT 解决方案:

select a from table where b = 1
intersect
select a from table where b = 2

编辑:

GROUP BY 查询 也许HAVING count distinct 版本更快:

select a from table
where b in (1,2)
group by a
having max(b) <> min(b)

【讨论】:

  • 因其可扩展性而成为答案。不幸的是 MySQL 不支持 INTERSECT。无论如何,GROUP BY 解决方案是可扩展的,可以根据匹配的数量(1 到 n)轻松生成此查询的代码。
  • 不知道是 MySQL。不能给mysql打标签吗?
  • @jarlh:如果我错了,请纠正我,但我并没有明确地试图用 MySQL 来质疑它。我正在使用 MySQL,是的,但我想知道在 SQL 中执行操作的一般方式/方法。所以我觉得没必要。
  • 随心所欲。但是 dbms 产品可能会以不同的方式优化事物,因此在某些情况下,一个查询可以用一个 dbms 运行得快,而用另一个 dbms 运行得慢。
【解决方案2】:

您可以使用 jarlh 中的 group by 方法或使用“distinct”进行联接:

select distinct a
from (select a from table where b = 1) t1
join (select a from table where b = 2) t2
  on t1.a = t2.a

【讨论】:

    【解决方案3】:

    类似这样(假设您需要按 B 中的特定 ID 进行过滤。

    SELECT DISTINCT A
    FROM Table AS T
    WHERE EXISTS (SELECT 1 from Table WHERE Table.A = T.A and B = 1)
    AND EXISTS (SELECT 1 from Table WHERE Table.A = T.A and B = 2)
    

    【讨论】:

      【解决方案4】:

      试试这个

      SELECT A
      FROM Table
      WHERE EXISTS (
          SELECT 1
          FROM Table t1
          WHERE t1.A = Table.A 
              AND t1.B = 1
      )
      AND EXISTS (
          SELECT 1
          FROM Table t2 
          WHERE t2.A = Table.A 
              AND t2.B = 2
      )
      

      【讨论】:

      • 虽然这段代码可能会解决 OP 的问题,但几句话的解释会让每个人都更容易理解这个答案。
      【解决方案5】:
      • A 不能作为此处的主键,因为该列包含重复项。
      • 一种可能的解决方案:

        SELECT * FROM (SELECT A, group_concat(B, ',') AS C FROM tab GROUP BY A) s WHERE s.C = "1,2";

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-08
        • 1970-01-01
        • 2014-05-08
        • 1970-01-01
        相关资源
        最近更新 更多