You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL查询求助:找出受完全相同抗生素作用的细菌对

解决“找出受完全相同抗生素作用的细菌对”问题

嘿,这个任务确实有点绕,我来帮你理清楚正确的思路~首先得说,你原来的SQL语法有问题(b1.bid, b2.bid IN (...)这种写法不对,应该写成(b1.bid, b2.bid) IN (...)),而且逻辑上也没抓住核心——你当前的思路只能找出共享至少一种抗生素的细菌对,但不是拥有完全相同抗生素集合的对。

核心思路

要找出抗生素集合完全一致的细菌对,关键是给每个细菌的抗生素集合生成一个唯一的“签名”——只要两个细菌的抗生素集合完全相同,它们的签名就一模一样。然后我们只需要找出签名相同的细菌对就行。

具体实现步骤

这里用常见的SQL语法(比如PostgreSQL、SQL Server)来举例,不同数据库的聚合函数可能略有差异(比如MySQL用GROUP_CONCAT代替STRING_AGG):

  1. 生成细菌的抗生素签名
    先通过聚合函数把每个细菌对应的所有抗生素ID按顺序拼接成字符串(一定要排序,避免因为抗生素记录顺序不同导致签名不一样),同时处理没有任何抗生素作用的细菌:

    WITH BacteriaAntibioticSignatures AS (
      SELECT
        b.bid,
        -- 用COALESCE处理无抗生素的情况,统一标记为'NO_ANTIBIOTICS'
        COALESCE(STRING_AGG(e.aid::TEXT, ',' ORDER BY e.aid), 'NO_ANTIBIOTICS') AS antibiotic_signature
      FROM Bacteria b
      LEFT JOIN Effect e ON b.bid = e.bid
      GROUP BY b.bid
    )
    
  2. 关联找出签名相同的细菌对
    基于上面的签名结果,自连接找出签名一致的细菌,同时通过b1.bid < b2.bid避免重复配对(比如细菌A和细菌B,不会同时出现B和A的配对,也不会出现自己和自己配对):

    SELECT
      b1.name AS 细菌1名称,
      b1.bid AS 细菌1ID,
      b2.name AS 细菌2名称,
      b2.bid AS 细菌2ID
    FROM Bacteria b1
    JOIN BacteriaAntibioticSignatures bas1 ON b1.bid = bas1.bid
    JOIN BacteriaAntibioticSignatures bas2 ON bas1.antibiotic_signature = bas2.antibiotic_signature
    JOIN Bacteria b2 ON bas2.bid = b2.bid
    WHERE b1.bid < b2.bid;
    

为什么这个方法可行?

  • STRING_AGG(..., ORDER BY aid)保证了相同的抗生素集合会生成完全一致的字符串,不管这些抗生素在Effect表中的存储顺序。
  • 左连接Bacteria表再分组,确保所有细菌都被包含(包括没有任何抗生素作用的)。
  • b1.bid < b2.bid的条件避免了重复的配对结果,让输出更简洁。

如果你用的是MySQL,只需要把STRING_AGG换成GROUP_CONCAT,其他逻辑一样:

WITH BacteriaAntibioticSignatures AS (
  SELECT
    b.bid,
    COALESCE(GROUP_CONCAT(e.aid ORDER BY e.aid SEPARATOR ','), 'NO_ANTIBIOTICS') AS antibiotic_signature
  FROM Bacteria b
  LEFT JOIN Effect e ON b.bid = e.bid
  GROUP BY b.bid
)
-- 后续关联查询和上面一样

内容的提问来源于stack exchange,提问作者Average_guy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:13:50