mysql - SQL 从表 1 中查找不在表 2 中或在表 2 中的记录(带条件)

标签 mysql sql left-join exists impala

我看到很多关于如何查找不在另一个表中的记录的示例,但是我在查找不在表 2 中或在表 2 中的记录时遇到了很多麻烦,但 freq 列值为低于10%。

我首先加入带有 BRCA1、BRCA2 和任何以 BRC 开头的基因的整体基因名称的变体列表,其中变体位于起始位置和终止位置之间。

从这些结果中,我想检查 kaviar 等位基因频率 (k) 并返回 kaviar 表中没有条目的结果,或者 kaviar 表中 alle_freq < .10 的结果。第一次连接的结果需要通过 chr、pos、ref 和 alt 与 kaviar 进行匹配。

我已经尝试过:

SELECT DISTINCT *
FROM puzz p, ensembl ens, kaviar k
WHERE (ens.gene_name IN ('BRCA1', 'BRCA2')
   OR ens.gene_name LIKE 'RAS%')
AND p.chr = ens.chromosome
AND p.pos >= ens.start AND p.pos <= ens.stop
AND NOT EXISTS
 (SELECT k.chromosome, k.pos, k.ref, k.alt, k.alle_freq, k.alle_cnt
  FROM public_hg19.kaviar k
  WHERE  p.chr = k.chromosome
  AND p.pos = k.pos
  AND p.ref = k.ref
  AND p.alt = k.alt
  )
  AND p.pos = k.pos
  AND p.ref = k.ref
  AND p.alt = k.alt
  AND k.alle_freq < .10

我也尝试过:

WITH puzz AS (
SELECT * 
FROM puzz p
WHERE p.gt IS NOT NULL
)

SELECT DISTINCT t1.*, kav.*
FROM
(SELECT puzz.*, ens.*
FROM puzz, public_hg19.ensembl_genes AS ens
WHERE (ens.gene_name IN IN ('BRCA1', 'BRCA2')
   OR ens.gene_name LIKE 'RAS%')
AND puzz.chr = ens.chromosome
AND puzz.pos BETWEEN ens.start AND ens.stop
AND ens.chromosome NOT LIKE "H%") t1

LEFT JOIN  

public_hg19.kaviar as kav
ON kav.chromosome = t1.chr
AND kav.pos = t1.pos
AND kav.ref = t1.ref
AND kav.alt = t1.alt
AND (kav.alle_freq < .10 OR kav.alle_freq IS NULL)

解决方案: 感谢@John Bollinger 提供了解决方案的框架。

由于 Impala 没有索引,最快的解决方案是创建一个临时表,以缩小传递给字符串操作的行数,如 ens 临时表所示。

WITH ens AS (
 SELECT DISTINCT chromosome as chr, start, stop, gene_name
   FROM public_hg19.ensembl_genes
  WHERE (gene_name IN ( 'BRCA1', 'BRCA2')
     OR gene_name LIKE 'RAS%')
    AND chromosome NOT LIKE "H%"
)
SELECT p.*, k.chromosome, k.pos, k.id, k.ref, k.alt,
       k.qual, (k.alle_freq * 100) as kav_freqPct, k.alle_cnt as kav_count
  FROM
(SELECT DISTINCT p.sample_id, p.chr, p.pos, p.id,
                 p.ref, p.alt, p.qual, p.filter,
                 ens.gene_name
  FROM ens, p7_ptb.itmi_102_puzzle p
  WHERE p.chr = ens.chr
  AND p.gt IS NOT NULL
  AND p.pos >= ens.start AND p.pos <= ens.stop
) AS p
LEFT JOIN public_hg19.kaviar k
      ON p.chr = k.chromosome
      AND p.pos = k.pos
      AND p.ref = k.ref
      AND p.alt = k.alt
WHERE COALESCE(k.alle_freq, 0.0) < .10

正如 @Gordon Linoff 所指出的,以下行也可以是

WHERE (k.alle_freq IS NULL OR k.alle_freq < 0.10)

两个最终子句返回相同的结果,但在 impala 上,合并函数在某种程度上更快。

最佳答案

您提出的两个查询似乎不匹配。表名称不同,并且某些过滤条件根本不相关。特别是,条件 AND ens.chromosome NOT LIKE "H%" (及其不正确的引号)从何而来?

我确实认为您的外连接方法很有前途,但我不明白为什么您需要 CTE 或内联 View 。

此外,“任何以‘BRC’开头的基因”包括“BRCA1”和“BRCA2”,因此您无需单独测试它们。删除冗余条件可能会稍微提高性能。

此外,如果您的数据结构碰巧会排除重复行,那么显式选择 DISTINCT 行对您没有帮助,反而可能会伤害您。 (尽管如此,我遵循您的指导,将其包含在我建议的查询中。)如果有很多结果,那么 SELECT DISTINCT 的成本就很高;尤其是当您选择很多列时。

这似乎准确地表达了您描述的查询:

SELECT DISTINCT
  p.sample_id, p.chr, p.pos, p.ref,
  p.alt, p.gt, p.qual, p.filter
FROM
  p7_ptb.itmi_102_puzzle p
  join public_hg19.ensembl_genes ens
    ON p.chr = ens.chromosome
  left join public_hg19.kaviar k
    ON p.chr = k.chromosome
      AND p.pos = k.pos
      AND p.ref = k.ref
      AND p.alt = k.alt
WHERE
  ens.gene_name LIKE 'BRC%'
  AND ens.chromosome NOT LIKE 'H%'
  AND p.pos BETWEEN ens.start AND ens.stop
  AND COALESCE(k.alle_freq, 0.0) < .10

如果它对您来说不够快,那么您需要检查您的查询计划以确定瓶颈是什么,而不是试图猜测。

关于mysql - SQL 从表 1 中查找不在表 2 中或在表 2 中的记录(带条件),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29997704/

相关文章:

mySQL 结合两个表我得到更多结果

mysql - 连接2个表SQL

java - 如何在 Ebean 中对两个参数进行左连接?

mysql - 如何连接表以选择连接表中的最大行?

php - 如何使用json检索数据到mysql android

mysql - 在数据库的未知表中查找特定列?

mysql - 非活跃客户mysql查询优化

sql - 将临时表连接到实际表

mysql - 外键力独特

tsql - 请帮助将 Tsql "implicit joins"转换为显式的