重写查询以使用子查询?

时间:2012-11-29 01:38:27

标签: sql

我是一个有sql的真正的菜鸟,但有人能告诉我如何使这个查询使用“subquerys”而不是?...而不是加入表格,这就是我现在正在做的猜测:

select Produkt.Namn from Produkt, Kund, InkOrder
where Produkt.ProdId = InkOrder.ProdId 
AND InkOrder.KundId = Kund.KundId
AND InkOrder.Datum = '2011-09-24'
AND Kund.Namn = 'Allstad'

1 个答案:

答案 0 :(得分:2)

让我们先使用连接重写查询:

SELECT Produkt.Namn
  FROM Produkt
  JOIN InkOrder ON Produkt.ProdId  = InkOrder.ProdId
  JOIN Kund     ON InkOrder.KundId = Kund.KundId
 WHERE InkOrder.Datum = '2011-09-24'
   AND Kund.Namn = 'Allstad'

然后我们可以注意到WHERE子句中的条件可以下推到ON子句中:

SELECT Produkt.Namn
  FROM Produkt
  JOIN InkOrder ON Produkt.ProdId  = InkOrder.ProdId AND InkOrder.Datum = '2011-09-24'
  JOIN Kund     ON InkOrder.KundId = Kund.KundId AND Kund.Namn = 'Allstad'

所以,如果一个子查询真的是一个好主意(它可能不是,但是优化器很可能会发现它并且像加入一样处理它),那么我们可以写:

SELECT Produkt.Namn
  FROM Produkt
  JOIN InkOrder ON Produkt.ProdId  = InkOrder.ProdId AND InkOrder.Datum = '2011-09-24'
 WHERE InkOrder.KundId IN (SELECT KundID FROM Kund WHERE Namn = 'Allstad')

然后使用以下内容获取第二个子查询:

SELECT Produkt.Namn
  FROM Produkt
 WHERE Produkt.ProdId IN
       (SELECT ProdId
          FROM InkOrder
         WHERE Datum = '2011-09-24'
           AND KundId IN (SELECT KundID FROM Kund WHERE Namn = 'Allstad')
       )

OTOH,具有显式JOIN操作的版本是迄今为止最清晰的版本。您可以在ON子句中编写过滤条件,但在(主)WHERE子句中编写它们可能更为明确,让优化器将过滤条件降低。这是一个非常重要的优化,任何生产质量的DBMS都不可能不进行优化。