【问题标题】:Pull back rows from multiple tables with a sub-select?使用子选择从多个表中拉回行?
【发布时间】:2010-11-15 04:20:48
【问题描述】:

我有一个脚本,它以以下方式生成查询(基于用户输入):

SELECT * FROM articles 
 WHERE (articles.skeywords_auto ilike '%pm2%') 
  AND spubid IN (
   SELECT people.spubid FROM people 
   WHERE (people.slast ilike 'chow') 
   GROUP BY people.spubid) 
 LIMIT 1;

生成的数据集:

Array ( [0] => 
  Array ( 
          [spubid] => A00603 
          [bactive] => t 
          [bbatch_import] => t 
          [bincomplete] => t 
          [scitation_vis] => I,X 
          [dentered] => 2009-07-24 17:07:27.241975 
          [sentered_by] => pubs_batchadd.php 
          [drev] => 2009-07-24 17:07:27.241975 
          [srev_by] => pubs_batchadd.php 
          [bpeer_reviewed] => t 
          [sarticle] => Errata: PM2.5 and PM10 concentrations from the Qalabotjha low-smoke fuels macro-scale experiment in South Africa (vol 69, pg 1, 2001) 
          [spublication] => Environmental Monitoring and Assessment 
          [ipublisher] => 
          [svolume] => 71 
          [sissue] => 
          [spage_start] => 207 
          [spage_end] => 210 
          [bon_cover] => f 
          [scover_location] => 
          [scover_vis] => I,X 
          [sabstract] => 
          [sabstract_vis] => I,X 
          [sarticle_url] => 
          [sdoi] => 
          [sfile_location] => 
          [sfile_name] => 
          [sfile_vis] => I
          [sscience_codes] => 
          [skeywords_manual] => 
          [skeywords_auto] => 1,5,69,2001,africa,assessment,concentrations,environmental,errata,experiment,fuels,low-smoke,macro-scale,monitoring,pg,pm10,pm2,qalabotjha,south,vol 
          [saward_number] => 
          [snotes] => 

)

问题是我还需要“人员”表中的所有列(在子选择中引用)作为数据集的一部分返回。过去我(显然)没有对子选择做太多事情,所以这种方法对我来说是非常新的。如何从文章表中拉回所有匹配的行/列作为人员表中的行/列?

【问题讨论】:

  • 你能处理一下格式吗?
  • 有人能解释一下 JOIN 和 INNTER JOIN 之间的主要区别吗? SELECT * FROM ARTICLES t JOIN PEOPLE p ON p.spubid = t.spubid AND p.saffil = 'DAS' WHERE t.skeywords_auto ILIKE'%pm2%';对比: SELECT a.*, p.* FROM article as a INNER JOIN people as p ON a.spubid = p.spubid WHERE a.skeywords_auto ilike '%pm2%' AND p.saffil = 'DAS';我得到了相同的结果集。
  • 显然格式不会在 cmets 中得到延续...#hrmph
  • JOIN 和 INNER JOin 是一回事
  • 这里是另一个问题,在某些情况下我嵌套子选择——如何通过连接来完成这个? SELECT * FROM 文章 WHERE (articles.skeywords_auto ilike '%test%') AND spubid IN (SELECT people.spubid FROM people WHERE (people.saffil = 'DHS') GROUP BY people.spubid) AND spubid IN (SELECT status.spubid FROM status WHERE (status.iyear >= 2000))

标签: sql database postgresql select


【解决方案1】:

您熟悉联接吗?使用 ANSI 语法:

SELECT DISTINCT *
  FROM ARTICLES t
  JOIN PEOPLE p ON p.spubid = t.spudid AND p.slast ILIKE 'chow'
 WHERE t.skeywords_auto ILIKE'%pm2%'
 LIMIT 1;

DISTINCT 不必为从两个表返回的每一列定义一个 GROUP BY。我包含它是因为您的子查询中有 GROUP BY;不知道有没有必要。

【讨论】:

  • 最终决定采用这个解决方案: SELECT * FROM article AS a INNER JOIN people AS p ON a.spubid = p.spubid INNER JOIN status as s on a.spubid = s.spubid WHERE a. skeywords_auto ilike '%pm2%' AND p.saffil = 'DAS' AND p.slast ilike '%Chow%' AND s.iyear >= 2000;
【解决方案2】:

在这种情况下你能不使用连接而不是子选择吗?

SELECT a.*, p.*
FROM articles as a
INNER JOIN people as p ON a.spubid = p.spubid
WHERE a.skeywords_auto ilike '%pm2%'
AND p.slast ilike 'chow'
LIMIT 1;

【讨论】:

  • JOIN 和 WHERE 子句中使用的括号不是必需的。
  • 已编辑。虽然我通常将它们放在 ON 子句中。
【解决方案3】:

让我们从头开始

  • 您不需要分组依据。改为使用 distinct(您没有在内部查询中进行任何聚合)。
  • 要查看内表的内容,实际上必须加入它。除非它显示在 from 部分中,否则不会公开内容。从 people 表到 article 表的左外连接应该等同于 IN 查询:

    SELECT *
    FROM people 
    LEFT OUTER JOIN articles ON articles.spubid = people.spubid 
    WHERE people.slast ilike 'chow' 
    AND articles.skeywords_auto ilike '%pm2%' 
    LIMIT 1
    

【讨论】:

    猜你喜欢
    • 2018-12-16
    • 2014-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-06
    • 1970-01-01
    • 2015-04-11
    相关资源
    最近更新 更多