带WHERE子句的JOIN之后的SQL WHERE语句

时间:2018-10-12 10:47:56

标签: sql sql-server

我试图选择一些数据,我将3个表连接在一起,但是其中一个连接具有where语句。完成连接后,我需要添加另一个where语句以选择日期范围和位置。在第二个WHERE子句中出现错误。

  SELECT a.[ID]
      ,a.[item_no]
      ,a.[qty]
  FROM [MYDB].[dbo].[details] AS a


  INNER JOIN [MYDB].[dbo].[delivery] AS b
  ON a.[item_no] = b.[item_no]
  INNER JOIN [MYDB].[dbo].[options] AS c
  ON a.[number] = c.[number] 
  WHERE a.[item_no] = c.[item_no]

WHERE b.[destination] = 'my destination'
AND b.[date] BETWEEN '2018-10-14' AND '2018-10-15' 

非常感谢您的帮助。

谢谢

7 个答案:

答案 0 :(得分:5)

尝试以下

SELECT a.[ID]
      ,a.[item_no]
      ,a.[qty]
  FROM [MYDB].[dbo].[details] AS a


  INNER JOIN [MYDB].[dbo].[delivery] AS b
  ON a.[item_no] = b.[item_no]
  INNER JOIN [MYDB].[dbo].[options] AS c
  ON a.[number] = c.[number] 
  and a.[item_no] = c.[item_no]

WHERE b.[destination] = 'my destination'
AND b.[date] BETWEEN '2018-10-14' AND '2018-10-15' 

答案 1 :(得分:3)

在JOIN语句中使用AND代替WHERE

答案 2 :(得分:2)

只需添加WHERE子句并将a.[item_no] = c.[item_no]ON子句一起移动:

SELECT a.[ID], a.[item_no], a.[qty]
FROM [MYDB].[dbo].[details] AS a INNER JOIN 
     [MYDB].[dbo].[delivery] AS b
     ON a.[item_no] = b.[item_no] INNER JOIN 
     [MYDB].[dbo].[options] AS c 
     ON a.[number] = c.[number] AND a.[item_no] = c.[item_no]
WHERE b.[destination] = 'my destination' AND
      b.[date] BETWEEN '2018-10-14' AND '2018-10-15'; 

答案 3 :(得分:2)

每个查询只有一个where子句。这应该是您想要做的:

SELECT d.[ID], d.[item_no], d.[qty]
FROM [MYDB].[dbo].[details] d JOIN
     MYDB].[dbo].[delivery] dv
     ON d.[item_no] = dv.[item_no] JOIN
     [MYDB].[dbo].[options] o
     ON d.[number] = o.[number] AND d.[item_no] = o.[item_no]
WHERE dv.[destination] = 'my destination' AND
      dv.[date] BETWEEN '2018-10-14' AND '2018-10-15' ;

您会注意到,我将表别名更改为表的缩写。有意义的表别名使查询更易于阅读和维护。

第一个WHERE子句中的条件是JOIN条件。它实际上属于ON子句,而不是WHERE子句。

答案 4 :(得分:2)

已经发布了许多答案,可以帮助您修复代码,但是我想明确解决导致您遇到问题的误解。在您的问题中,您说:

  

...其中一个联接具有where语句。

但这是不正确的。 WHERE子句是SELECT语句的一部分,而不是JOIN的一部分。

从广义上讲,SQL引擎通过查看FROM子句开始解释您的查询。本质上,它首先询问您的数据来自何处。您的FROM子句包括您的基本表[MYDB].[dbo].[details]以及要加入的任何其他表。 ON的{​​{1}}条件告诉引擎表中的哪些字段具有相应的数据点。在JOIN的情况下,这可能会限制结果数据集,这也是INNER JOIN子句的结果,但是WHERE产生的过滤会发生在查询开始时,当引擎将数据提取到内存中时,您的查询将被处理。

建立初始数据集之后,引擎将读取JOIN子句并应用在此指定的所有过滤器。

这是关于Logical Processing Order of the SELECT statement的MSDN讨论。

您可以在WHERE中指定多个ON条件,以限制提取到初始数据集中的数据量。例如,您的第一个JOIN可以这样重写:

JOIN

使用INNER JOIN [MYDB].[dbo].[delivery] AS b ON a.[item_no] = b.[item_no] AND b.[date] BETWEEN '2018-10-14' AND '2018-10-15' ,将过滤条件放入INNER JOINJOIN之间并没有太大(任何)区别,但是使用WHERE,结果可以,而且它们之间会有很大的不同,因此了解OUTER JOIN语句中每个组件的作用以及执行的时间非常重要。

由于所有联接均为SELECT,因此您的查询实际上可能根本没有INNER子句,如下所示:

WHERE

在内存不足的系统上,SELECT a.[ID] ,a.[item_no] ,a.[qty] FROM [MYDB].[dbo].[details] AS a INNER JOIN [MYDB].[dbo].[delivery] AS b ON a.[item_no] = b.[item_no] AND b.[destination] = 'my destination' AND b.[date] BETWEEN '2018-10-14' AND '2018-10-15' INNER JOIN [MYDB].[dbo].[options] AS c ON a.[number] = c.[number] AND a.[item_no] = c.[item_no] 子句中的过滤可以减少内存压力,我已经用过这种方法,但是大多数人发现ON子句更具可读性,因为那就是我们通常寻找数据过滤器的地方。

答案 5 :(得分:1)

您只需要扩展现有的 WHERE 子句即可。

SELECT a.[ID]
      ,a.[item_no]
      ,a.[qty]
  FROM [MYDB].[dbo].[details] AS a
  INNER JOIN [MYDB].[dbo].[delivery] AS b
  ON a.[item_no] = b.[item_no]
  INNER JOIN [MYDB].[dbo].[options] AS c
  ON a.[number] = c.[number] 
  WHERE a.[item_no] = c.[item_no] AND b.[destination] = 'my destination'
AND b.[date] BETWEEN '2018-10-14' AND '2018-10-15' 

答案 6 :(得分:1)

如果表中包含大量数据,并且您想与其他表一起应用联接会导致性能问题,请先在表的子查询中过滤数据,然后再与其他表一起应用联接,以便在与表一起应用联接时减少循环执行,有关更多详细信息,您可以检查执行计划和查询流程步骤

  SELECT a.[ID]
   ,a.[item_no]
  ,a.[qty]
 FROM [MYDB].[dbo].[details] AS a


INNER JOIN (Select * from  [MYDB].[dbo].[delivery] 
WHERE [destination] = 'my destination'
AND [date] BETWEEN '2018-10-14' AND '2018-10-15' ) AS b
 ON a.[item_no] = b.[item_no]
INNER JOIN [MYDB].[dbo].[options] AS c
ON a.[number] = c.[number] 
and a.[item_no] = c.[item_no]