Sql server TSQL更新与选择连接问题
我拿了一些本应该有效的代码,但发现它没有按设计的那样有效, 坦率地说,我努力想得到什么是错误的,我需要填满所有的篮子,但现在只有第一次被填满,我需要做任何支点吗??或者用select删除更新?我希望有相同的5个Tx行,并为所有TXD填充所有篮子,下面这个自包含示例将说明这一点:Sql server TSQL更新与选择连接问题,sql-server,tsql,Sql Server,Tsql,我拿了一些本应该有效的代码,但发现它没有按设计的那样有效, 坦率地说,我努力想得到什么是错误的,我需要填满所有的篮子,但现在只有第一次被填满,我需要做任何支点吗??或者用select删除更新?我希望有相同的5个Tx行,并为所有TXD填充所有篮子,下面这个自包含示例将说明这一点: SELECT * INTO #lkup FROM ( -- drop table #lkup -- select * from #lkup SELECT 201 Cust_ID, 1
SELECT * INTO #lkup FROM ( -- drop table #lkup -- select * from #lkup
SELECT 201 Cust_ID, 1 Line, 'Pr1' ProductID UNION
SELECT 201 Cust_ID, 2 Line, 'Pr20' ProductID UNION
SELECT 201 Cust_ID, 3 Line, 'Pr333' ProductID ) g
SELECT * INTO #tx FROM ( -- drop table #tx -- select * from #tx
SELECT 201 Cust_ID, cast (NULL AS varchar(7)) Prod1, cast (NULL AS varchar(7)) Prod2, cast (NULL AS varchar(7)) Prod3 , 12001 TxID UNION
SELECT 201 Cust_ID, cast (NULL AS varchar(7)) Prod1, cast (NULL AS varchar(7)) Prod2, cast (NULL AS varchar(7)) Prod3 , 12002 TxID UNION
SELECT 201 Cust_ID, cast (NULL AS varchar(7)) Prod1, cast (NULL AS varchar(7)) Prod2, cast (NULL AS varchar(7)) Prod3 , 12003 TxID UNION
SELECT 201 Cust_ID, cast (NULL AS varchar(7)) Prod1, cast (NULL AS varchar(7)) Prod2, cast (NULL AS varchar(7)) Prod3 , 12004 TxID UNION
SELECT 201 Cust_ID, cast (NULL AS varchar(7)) Prod1, cast (NULL AS varchar(7)) Prod2, cast (NULL AS varchar(7)) Prod3 , 12005 TxID ) g
UPDATE tx
SET Prod1 = CASE WHEN LINE =1 THEN ProductID END,
Prod2 = CASE WHEN LINE =2 THEN ProductID END,
Prod3 = CASE WHEN LINE =3 THEN ProductID END
--- SELECT l.Line, l.ProductID, tx.*
FROM #tx tx
JOIN #lkup l ON l.Cust_ID = tx.Cust_ID
SELECT * FROM #tx -- update #tx set Prod1 = ' ', Prod2 = ' ', Prod3 = ' '
SELECT 'Shouldbe' , '201' CustID, 'Pr1' Prod1, 'Pr20' Prod1, 'Pr333' Prod1, 12001 TxID -- for each Tx 5 rows Total
您可以使用此代码块
UPDATE tx
SET Prod1 = l.ProductID,
Prod2 = l2.ProductID,
Prod3 = l3.ProductID
--- SELECT l.Line, l.ProductID, tx.*
FROM #tx tx
LEFT JOIN #lkup l ON l.Cust_ID = tx.Cust_ID AND l.Line=1
LEFT JOIN #lkup l2 ON l2.Cust_ID = tx.Cust_ID AND l2.Line=2
LEFT JOIN #lkup l3 ON l3.Cust_ID = tx.Cust_ID AND l3.Line=3
您可以使用此代码块
UPDATE tx
SET Prod1 = l.ProductID,
Prod2 = l2.ProductID,
Prod3 = l3.ProductID
--- SELECT l.Line, l.ProductID, tx.*
FROM #tx tx
LEFT JOIN #lkup l ON l.Cust_ID = tx.Cust_ID AND l.Line=1
LEFT JOIN #lkup l2 ON l2.Cust_ID = tx.Cust_ID AND l2.Line=2
LEFT JOIN #lkup l3 ON l3.Cust_ID = tx.Cust_ID AND l3.Line=3
当然,问题是您要多次更新相同的行。奇怪的是,这不是一个错误,但如果我正确理解了您的代码,您可以这样做:
UPDATE tx
SET tx.Prod1 = L.Prod1,
tx.Prod2 = L.Prod2,
tx.Prod3 = L.Prod3
FROM #tx tx
cross apply (
SELECT
Cust_ID,
Prod1 = max(CASE WHEN LINE =1 THEN ProductID END),
Prod2 = max(CASE WHEN LINE =2 THEN ProductID END),
Prod3 = max(CASE WHEN LINE =3 THEN ProductID END)
FROM #lkup
group by Cust_ID
) L where L.Cust_ID = tx.Cust_ID
结果:
Cust_ID Prod1 Prod2 Prod3 TxID
1 201 Pr1 Pr20 Pr333 12001
2 201 Pr1 Pr20 Pr333 12002
3 201 Pr1 Pr20 Pr333 12003
4 201 Pr1 Pr20 Pr333 12004
5 201 Pr1 Pr20 Pr333 12005
当然,问题是您要多次更新相同的行。奇怪的是,这不是一个错误,但如果我正确理解了您的代码,您可以这样做:
UPDATE tx
SET tx.Prod1 = L.Prod1,
tx.Prod2 = L.Prod2,
tx.Prod3 = L.Prod3
FROM #tx tx
cross apply (
SELECT
Cust_ID,
Prod1 = max(CASE WHEN LINE =1 THEN ProductID END),
Prod2 = max(CASE WHEN LINE =2 THEN ProductID END),
Prod3 = max(CASE WHEN LINE =3 THEN ProductID END)
FROM #lkup
group by Cust_ID
) L where L.Cust_ID = tx.Cust_ID
结果:
Cust_ID Prod1 Prod2 Prod3 TxID
1 201 Pr1 Pr20 Pr333 12001
2 201 Pr1 Pr20 Pr333 12002
3 201 Pr1 Pr20 Pr333 12003
4 201 Pr1 Pr20 Pr333 12004
5 201 Pr1 Pr20 Pr333 12005
极有吸引力的它可能是未定义或不确定的行为。尝试用RIGHT JOIN替换update语句的JOIN,看看会发生什么。你能用子查询把CASE重写成lkup吗?我试着用括号中的Select来代替CASE,但没有用,可能是更新语法的b'z。使用RIGHT JOIN,它现在可以捕获Prod1和Prod3,但仍然不能捕获Prod2。更正:这确实有效,但将是我的最后手段,我有太多的篮子,在实际设置中,我在JOIN中嵌套了select。更新tx SET tx.Prod1=从lkup l中选择l.ProductID,其中l.Cust_ID=tx.Cust_ID,LINE=1您认为这项工作会如何进行?它应该使用tx中的哪一行作为值?您的连接条件本质上是与示例数据的交叉连接。Tx,是的,它是交叉连接,我看到了15行,但每行仍然有行,我实际上感到惊讶的是,它作为对多个值的同类更新工作。我假设它浏览了所有这些值,它应该捕捉到正确的行…非常有趣。它可能是未定义或不确定的行为。尝试用RIGHT JOIN替换update语句的JOIN,看看会发生什么。你能用子查询把CASE重写成lkup吗?我试着用括号中的Select来代替CASE,但没有用,可能是更新语法的b'z。使用RIGHT JOIN,它现在可以捕获Prod1和Prod3,但仍然不能捕获Prod2。更正:这确实有效,但将是我的最后手段,我有太多的篮子,在实际设置中,我在JOIN中嵌套了select。更新tx SET tx.Prod1=从lkup l中选择l.ProductID,其中l.Cust_ID=tx.Cust_ID,LINE=1您认为这项工作会如何进行?它应该使用tx中的哪一行作为值?您的连接条件本质上是与示例数据的交叉连接。Tx,是的,它是交叉连接,我看到了15行,但每行仍然有行,我实际上感到惊讶的是,它作为对多个值的同类更新工作。我假设它浏览了所有这些值,它应该捕捉到正确的行。。。