使用连接表的 AVG 进行 SQL 更新
Posted
技术标签:
【中文标题】使用连接表的 AVG 进行 SQL 更新【英文标题】:SQL Update with AVG of Joined Tables 【发布时间】:2020-02-15 10:59:09 【问题描述】:我正在尝试通过计算订单日期和库存收货日期之间的差异来更新表格中的供应商提前期....
UPDATE cr_accs
SET cr_accs.leadtime = Avg(Datediff(day, purchord_hdr.orderdate,
stock_trans.transdate))
FROM stock_items
INNER JOIN stock_trans
ON stock_trans.stockcode = stock_items.stockcode
INNER JOIN purchord_hdr
ON purchord_hdr.seqno = stock_trans.ref1
WHERE cr_accs.accno = purchord_hdr.accno
AND stock_trans.location = 1
AND stock_trans.ref2 = 'RECEIPT'
AND purchord_hdr.orderdate >= Dateadd(day, Datediff(day, 0, Getdate()),-730)
AND stock_items.isactive = 'Y'
AND stock_items.bincode NOT IN ( 'OIO', 'CON' )
但是我得到一个错误
聚合可能不会出现在 UPDATE 语句的集合列表中
我见过其他解决方案,您可以将查询更改为:
UPDATE cr_accs
SET cr_accs.leadtime = h.calc_lead_time
FROM (SELECT AVG(DATEDIFF(day, purchord_hdr.orderdate, stock_trans.transdate)) AS calc_lead_time
FROM stock_items
INNER JOIN stock_trans
ON stock_trans.stockcode = stock_items.stockcode
INNER JOIN purchord_hdr
ON purchord_hdr.seqno = stock_trans.ref1
INNER JOIN cr_accs
ON cr_accs.accno = purchord_hdr.accno
WHERE cr_accs.accno = purchord_hdr.accno
AND stock_trans.location = 1
AND stock_trans.ref2 = 'RECEIPT'
AND purchord_hdr.orderdate >= Dateadd(day, Datediff(day, 0, Getdate()),-730)
AND stock_items.isactive = 'Y'
AND stock_items.bincode NOT IN ( 'OIO', 'CON' ) ) h
但这不是我的解决方案,因为它没有定义每个供应商的交货时间都是独一无二的...... 指出每个供应商都由 cr_accs.accno 标识可能会有所帮助
有什么想法吗?
【问题讨论】:
您使用的是哪种 DBMS 产品? “SQL”只是一种查询语言,而不是特定数据库产品的名称(在标准 SQL 中,UPDATE 命令没有FROM
子句)。 Why should I tag my DBMS
【参考方案1】:
您还可以使用相关子查询来做您想做的事情,这可能是您想要做的事情:
UPDATE cr_accs
SET cr_accs.leadtime =
(SELECT AVG(DATEDIFF(day, p.orderdate, st.transdate)) AS calc_lead_time
FROM stock_items si JOIN
stock_trans st
ON st.stockcode = si.stockcode JOIN
purchord_hdr p
ON p.seqno = st.ref1
WHERE cr_accs.accno = p.accno AND
st.location = 1 AND
st.ref2 = 'RECEIPT' AND
p.orderdate >= Dateadd(day, Datediff(day, 0, Getdate()), -730) AND
si.isactive = 'Y' AND
si.bincode NOT IN ( 'OIO', 'CON' )
);
我引入了表别名,以便查询更易于编写和阅读。
SQL Server 还使您能够使用APPLY
表达这一点:
UPDATE a
SET a.leadtime = p.calc_lead_time
FROM cr_accs a CROSS APPLY
(SELECT AVG(DATEDIFF(day, p.orderdate, st.transdate)) AS calc_lead_time
FROM stock_items si JOIN
stock_trans st
ON st.stockcode = si.stockcode JOIN
purchord_hdr p
ON p.seqno = st.ref1
WHERE a.accno = p.accno AND
st.location = 1 AND
st.ref2 = 'RECEIPT' AND
p.orderdate >= Dateadd(day, Datediff(day, 0, Getdate()), -730) AND
si.isactive = 'Y' AND
si.bincode NOT IN ( 'OIO', 'CON' )
) p;
【讨论】:
谢谢 Gordon Linoff - 这确实有效,谢谢 :-) 您的答案会更新表格中的每个供应商交货时间,无论是否在两年内(> = 730 天)内进行了任何购买 - 在那里没有采购,交货时间为空......(正确)。 @forpas 解决方案也适用 - 但是只更新已经购买的供应商(902 行受影响,两个查询之间有 235 行)。因此,两者都是正确的,具体取决于您想要的结果。【参考方案2】:尝试将表连接到查询:
UPDATE c
SET c.leadtime = h.calc_lead_time
FROM cr_accs c
INNER JOIN (
SELECT purchord_hdr.accno,
AVG(DATEDIFF(day, purchord_hdr.orderdate, stock_trans.transdate)) AS calc_lead_time
FROM stock_items
INNER JOIN stock_trans ON stock_trans.stockcode = stock_items.stockcode
INNER JOIN purchord_hdr ON purchord_hdr.seqno = stock_trans.ref1
WHERE stock_trans.location = 1
AND stock_trans.ref2 = 'RECEIPT'
AND purchord_hdr.orderdate >= Dateadd(day, Datediff(day, 0, Getdate()),-730)
AND stock_items.isactive = 'Y'
AND stock_items.bincode NOT IN ('OIO', 'CON')
GROUP BY purchord_hdr.accno
) h ON h.accno = c.accno
我假设(根据您的代码和错误消息)您正在使用 SQL Server。
【讨论】:
以上是关于使用连接表的 AVG 进行 SQL 更新的主要内容,如果未能解决你的问题,请参考以下文章