我试图选择一些数据,我将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'
非常感谢您的帮助。
谢谢
答案 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 JOIN
或JOIN
之间并没有太大(任何)区别,但是使用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]