Sql server SQL SERVER-左联接不起作用。因为
这在MS Access中非常有效。 为什么不在MS SQL Server中 你能帮我解决吗Sql server SQL SERVER-左联接不起作用。因为,sql-server,Sql Server,这在MS Access中非常有效。 为什么不在MS SQL Server中 你能帮我解决吗 我怀疑这里的问题在于您对子查询如何工作的理解。我们有你的疑问: SELECT * FROM tblPROproduto pr LEFT JOIN (SELECT TOP (1) idproduto, valcusto FROM tblproestoque
我怀疑这里的问题在于您对子查询如何工作的理解。我们有你的疑问:
SELECT *
FROM tblPROproduto pr
LEFT JOIN (SELECT TOP (1)
idproduto,
valcusto
FROM tblproestoque
ORDER BY identrada DESC) tmp ON tmp.idproduto = pr.idproduto
WHERE pr.idproduto = 8183;
我们可以将其分为两个不同部分:
SELECT TOP (1)
idproduto,
valcusto
FROM tblproestoque
ORDER BY identrada DESC;
然后:
SELECT *
FROM tblPROproduto pr
LEFT JOIN tmp ON tmp.idproduto = pr.idproduto
WHERE pr.idproduto = 8183;
这可能会向你解释为什么你所拥有的不起作用。我猜您假定tmp上的ON子句是在选择子查询之前派生的。事实并非如此。将派生子查询,然后打开。因此,tmp的值将是在上述查询中重新返回的值
我想你想要的是:
SELECT *
FROM tblPROproduto pr
OUTER APPLY (SELECT TOP (1)
ca.idproduto,
ca.valcusto
FROM tblproestoque ca
WHERE ca.idproduto = pr.idproduto
ORDER BY ca.identrada DESC) tmp
WHERE pr.idproduto = 8183;
编辑:为OP添加了一些示例数据和解释,以帮助他们理解:
@拉斐尔布诺,你基本上需要一个外部应用程序。这在MSAccess中是不同的 见下文: 让我知道它是否有效
select *
from tblPROproduto pr
outer apply (select top(1) idproduto, valcusto
from tblproestoque tmp
where tmp.idproduto = pr.idproduto
order by identrada desc) tmp
where pr.idproduto = 8183
该链接指向Youtube。你的问题在哪里?以文本的形式发布。什么是with不起作用?我猜您的子查询不会返回您认为它会返回的结果,因为它没有where子句,而是您发布的前两个查询。尝试单独运行子查询并查看它返回的结果。idproduct,valcusto在左join上返回null,因为前1个查询也应该有where子句。on不能用于APPLY,并且这不会阻止在on之前解析子查询。如果子查询有效,则您是对的。现在已编辑。@Larnu,是的,有这个错误。@MEdwin您的解决方案成功了。非常感谢,我的朋友。谢谢大家helped@Larnu谢谢你的帮助和解释。他们帮了很多忙!有一个语法错误。关键字“WHERE”附近的语法不正确。@RafaelBueno抱歉,我错过了别名。伙计们,我不明白为什么这个简单的查询不能像Access一样完美地工作。表字段有什么问题吗?@RafaelBueno原因是子查询总是从tblproestoque返回前1,按identrada降序排列,而不管idproduto的值是多少。返回的行很可能没有idproduto的值8183,因此ON子句为false,并且没有返回值。@RafaelBueno希望该示例数据将帮助您了解SQL Server的工作方式。
USE Sandbox;
GO
CREATE TABLE Product (ID int IDENTITY(1,1),
Sku varchar(10),
ProductName varchar(25));
CREATE TABLE ProductOrder (ID int IDENTITY(1,1),
ProductID int,
OrderDate date,
NumberOrdered int);
INSERT INTO dbo.Product (Sku,
ProductName)
VALUES ('65432462','Lawn Mower'),
('98742347','Helicopter'),
('89465735','BBQ');
INSERT INTO dbo.ProductOrder (ProductID,
OrderDate,
NumberOrdered)
VALUES (1,'20180101',7),
(1,'20180708',19),
(2,'20180501',12),
(3,'20180804',27);
GO
SELECT *
FROM dbo.Product;
SELECT *
FROM dbo.ProductOrder;
GO
--Use the example the OP has in their post:
SELECT *
FROM dbo.Product P
LEFT JOIN (SELECT TOP 1 *
FROM dbo.ProductOrder
ORDER BY OrderDate DESC) PO ON PO.ProductID = P.ID
WHERE P.ID = 2;
--This returns NULLs for all the latter columns.
--Why?
--Inspect the subquery:
SELECT TOP 1 *
FROM dbo.ProductOrder
ORDER BY OrderDate DESC;
--Product ID 3? 3 != 2 so the ON clause fails:
--Demonstrate
SELECT *
FROM dbo.Product P
CROSS JOIN (SELECT TOP 1 * --CROSS JOIN joins all rows (creates a cartesian product)
FROM dbo.ProductOrder
ORDER BY OrderDate DESC) PO
WHERE P.ID = 2;
--The solution, use OUTER APPLY:
SELECT *
FROM dbo.Product P
OUTER APPLY (SELECT TOP 1 *
FROM dbo.ProductOrder oa
WHERE oa.ProductID = P.ID --WHERE clause, this is like your ON
ORDER BY oa.OrderDate DESC) PO
WHERE P.ID = 2;
GO
DROP TABLE dbo.ProductOrder;
DROP TABLE dbo.Product;
select *
from tblPROproduto pr
outer apply (select top(1) idproduto, valcusto
from tblproestoque tmp
where tmp.idproduto = pr.idproduto
order by identrada desc) tmp
where pr.idproduto = 8183