我在尝试执行UPDATE FROM查询的Azure SQL DW中收到错误。错误是UPDATE和DELETE语句中的" FROM子句不能包含子查询源或连接"
这仅仅是针对SQL DW吗?否则我不会发现此查询有任何问题。如果它是SQL DW的限制,可以选择什么?
-- Permanent fact table with 5 billion rows
CREATE TABLE FactTable (Id1 INT, Id2 INT, EmailAddress NVARCHAR(100), Value1 INT)
WITH (DISTRIBUTION = HASH(EmailAddress));
-- Staging fact table with 10 million rows
CREATE TABLE StageTable (Id1 INT, Id2 INT, EmailAddress NVARCHAR(100), Value1 INT)
WITH (DISTRIBUTION = HASH(EmailAddress), HEAP);
-- Add a secondary index that should help with joining to StageTable
CREATE NONCLUSTERED INDEX ix ON FactTable (Id1, Id2);
UPDATE fact
SET
Value1 = CASE WHEN stage.Value1 > fact.Value1 THEN stage.Value1 ELSE fact.Value1 END
FROM FactTable AS fact
INNER JOIN StageTable AS stage ON fact.Id1 = stage.Id1 AND fact.Id2 = stage.Id2
答案 0 :(得分:2)
根据the documentation Azure SQL数据仓库支持UPDATE
但不支持FROM
子句中的ANSI连接。您可以使用CTAS来解决问题。简单的两表更新:
UPDATE dbo.FactTable
SET
Value1 = CASE WHEN stage.Value1 > dbo.FactTable.Value1 THEN stage.Value1 ELSE dbo.FactTable.Value1 END
FROM dbo.StageTable AS stage
WHERE dbo.FactTable.Id1 = stage.Id1
AND dbo.FactTable.Id2 = stage.Id2;
CTAS更复杂的例子,从main UPDATE documentation page批发复制:
-- Create an interim table
CREATE TABLE CTAS_acs
WITH (DISTRIBUTION = ROUND_ROBIN)
AS
SELECT ISNULL(CAST([EnglishProductCategoryName] AS NVARCHAR(50)),0) AS [EnglishProductCategoryName]
, ISNULL(CAST([CalendarYear] AS SMALLINT),0) AS [CalendarYear]
, ISNULL(CAST(SUM([SalesAmount]) AS MONEY),0) AS [TotalSalesAmount]
FROM [dbo].[FactInternetSales] AS s
JOIN [dbo].[DimDate] AS d ON s.[OrderDateKey] = d.[DateKey]
JOIN [dbo].[DimProduct] AS p ON s.[ProductKey] = p.[ProductKey]
JOIN [dbo].[DimProductSubCategory] AS u ON p.[ProductSubcategoryKey] = u.[ProductSubcategoryKey]
JOIN [dbo].[DimProductCategory] AS c ON u.[ProductCategoryKey] = c.[ProductCategoryKey]
WHERE [CalendarYear] = 2004
GROUP BY
[EnglishProductCategoryName]
, [CalendarYear]
;
-- Use an implicit join to perform the update
UPDATE AnnualCategorySales
SET AnnualCategorySales.TotalSalesAmount = CTAS_ACS.TotalSalesAmount
FROM CTAS_acs
WHERE CTAS_acs.[EnglishProductCategoryName] = AnnualCategorySales.[EnglishProductCategoryName]
AND CTAS_acs.[CalendarYear] = AnnualCategorySales.[CalendarYear]
;
--Drop the interim table
DROP TABLE CTAS_acs
;
答案 1 :(得分:1)
我发现ASDW(和APS / PDW)是一个很好的做法,可以避免瘟疫之类的批量更新。
这是一种纯CTAS替代方案,在您更新大部分行的情况下会更快。
它假定id1是一个相对好的分发键,并且分段行的数量小于事实行,使复制可行。该策略应该消除节点之间的数据移动。
如果你有一个非常大的临时表,在每个表中创建一个代理列,它是id1和id2的组合,然后通过该列的哈希分配两个表,将会提供更好的性能。
android:paddingBottom="@dimen/dp10"
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/dp10">
答案 2 :(得分:0)
简化您的尝试将起作用。只需删除连接并从另一个表更新一个表。
update FactTable
set this = that
from StageTable s where s.something = FactTable.something
这是否是最佳方法取决于您的具体情况,但它会在不引发错误的情况下执行。