执行查询的最有效方法

时间:2016-02-01 22:04:05

标签: php mysql sql database join

我的目标是从外键值与其他表中子查询返回的ID匹配的表中获取所有记录。

我尝试过几种组合,但它们甚至无法编译。

要澄清,请考虑以下查询:

SELECT *
FROM   `news`
WHERE  IDFIRM IN (SELECT ID FROM firm WHERE Block=0)
AND    Actual=1

这是一个简单的查询,但除了此子查询中的ID之外,我还需要检索其他列并将其作为响应返回。

这样的事情(但当然这不起作用):

SELECT news.*, sub.name
FROM   `news`,
       (SELECT * FROM firm WHERE Block=0) AS sub
WHERE  news.IDFIRM IN (SELECT sub.ID FROM sub)
AND    news.Actual=1

我知道如何使用连接实现它,但问题是可以有多个IN语句(来自不同的表),如下所示:

SELECT *
FROM   `news`
WHERE  IDFIRM IN (SELECT ID FROM firm WHERE Block=0)
AND    Actual=1
AND    id_publisher IN (SELECT ID FROM publisher WHERE Block=0)

因此,根据请求,此查询可能会变得非常不同。

如何创建最有效的查询来解决此任务?或者只有多个查询才有可能?

感谢。

3 个答案:

答案 0 :(得分:1)

假设你的索引在JOIN的两边都是理智的,它们实际上会被利用,而子查询可能使用一面。

SELECT [column_list]
FROM news n
  INNER JOIN firm f
    ON n.idfirm = f.id
  INNER JOIN publisher p
    ON n.idpublisher = p.id
WHERE n.actual = 1
  AND f.block = 0
  AND p.block = 0

答案 1 :(得分:1)

您绝对应该使用JOIN代替IN (SELECT ...)

查询1:

SELECT *
FROM   `news`
WHERE  IDFIRM IN (SELECT ID FROM firm WHERE Block=0)
AND    Actual=1

将其替换为:

SELECT     news.*
FROM       news
INNER JOIN form ON news.IDFIRM = form.ID
WHERE      news.Actual=1

查询2:

SELECT news.*, sub.name
FROM   `news`,
       (SELECT * FROM firm WHERE Block=0) AS sub
WHERE  news.IDFIRM IN (SELECT sub.ID FROM sub)
AND    news.Actual=1

替换为:

SELECT     news.*,
           firm.name
FROM       news
INNER JOIN firm ON news.IDFIRM = firm.ID 
WHERE      news.Actual=1
AND        firm.Block=0

查询3:

SELECT *
FROM   `news`
WHERE  IDFIRM IN (SELECT ID FROM firm WHERE Block=0)
AND    Actual=1
AND    id_publisher IN (SELECT ID FROM publisher WHERE Block=0)

替换为:

SELECT     news.*
FROM       news
INNER JOIN firm      ON news.IDFIRM = firm.ID
INNER JOIN publisher ON news.id_publisher = publisher.ID
WHERE      news.Actual=1
AND        firm.Block=0
AND        publisher.Block=0

添加表格和条件

所以我的想法是你用这样的句子添加你需要的所有表:

INNER JOIN table1 ON news.<foreign-key> = table1.ID

并在WHERE子句中添加条件,如下所示:

WHERE   table1.field = <literal>
AND     table2.field = <other literal>
AND     ...

答案 2 :(得分:0)

您已经在建议加入。 你可以使用多个JOIN来获得你想要的东西。

$attach = $newdb->get_results( "SELECT ID,guid FROM pm_posts where post_type ='attachment' AND post_parent = $post_id");

我是从记忆中做到的,但我认为应该让你接近。