我们的数据库中有超过10万种产品,我们每10分钟向客户提供一份包含价格和许多其他数据的报告。我目前正在尝试重新编写查询以简化整个过程。在这一点上,我应该指出,我的SQL知识在过去几个月中是自学的,所以实际上只是一个新手。
我真正撞到墙上的部分是:
下面的WHERE
语句在没有任何更改并且我无法解决导致它或我做错的事情时返回结果事件。
UPDATE variant_external_analysis
SET vaea_d_1 = GETDATE(), -- last updated
vaea_n_3 = ROUND((vaea_n_12 + vaea_n_18) * (SELECT CAST(jn_our_ref AS FLOAT) FROM job_number WHERE jn_id='20'),2) -- product price
FROM variant_external_analysis
JOIN variant_detail ON vad_id = vaea_vad_id
WHERE
((vaea_n_3 <> ROUND((vaea_n_12 + vaea_n_18) * (SELECT CAST(jn_our_ref AS FLOAT) FROM job_number WHERE jn_id='20'),2)) -- has price change
OR vaea_n_3 IS NULL) -- Is price field empty
AND vad_variant_code BETWEEN 1000 AND 990000 -- product range for client
如果价格vaea_n_3
已更改或IS NULL
,它应该更新价格vaea_d_1
,同时在相同条件下更改最后更新日期vaea_n_3
。
但是由于某种原因,即使我连续运行查询多次,即使NULL
的任何产品都没有更改并且没有一个vaea_d_1
值,它仍然返回约6k产品
我需要(SELECT CAST(jn_our_ref AS FLOAT) FROM job_number WHERE jn_id='20')
,因此我们发送给客户的价格文件只能包括价格已经改变的产品,而不是全部10万产品。
任何人都可以请这个简单的查询出什么问题吗?
通过几个不同民族的答案的组合,证明问题出在
UPDATE variant_external_analysis
SET vaea_d_1 = GETDATE(), -- last updated
vaea_n_3 = ROUND((vaea_n_12 + vaea_n_18) * jna_n_7, 2) -- product price
FROM job_number_analysis, variant_external_analysis
JOIN variant_detail ON vad_id = vaea_vad_id
WHERE ((vaea_n_3 <> ROUND((vaea_n_12 + vaea_n_16) * jna_n_7, 2)) -- has price changed
OR vaea_n_3 IS NULL) -- Is price field empty
AND vad_variant_code BETWEEN 1000 AND 990000 -- product range for client
AND jna_jn_id = 59
因此,我重新编写了查询,并更改了存储全局变量的位置/方式:
list
这现在可以正常工作,并且仅在发生更改时才更新。谢谢大家提出的想法。
答案 0 :(得分:0)
不确定您的问题是什么,但这是使查询更快的一种方法:
SET vaea_d_1 = GETDATE(), -- last updated
vaea_n_3 = ROUND((vaea_n_12 + vaea_n_18) * (SELECT CAST(jn_our_ref AS FLOAT) FROM job_number WHERE jn_id='20'),2) -- product price
FROM variant_external_analysis
JOIN variant_detail ON vad_id = vaea_vad_id
WHERE ((vaea_n_3 <> ROUND((vaea_n_12 + vaea_n_18) * (SELECT CAST(jn_our_ref AS FLOAT) FROM job_number WHERE jn_id='20'),2)) -- has price change
OR vaea_n_3 IS NULL) -- Is price field empty
AND vad_variant_code BETWEEN 1000 AND 990000 -- product range for client
与
相同SET vaea_d_1 = GETDATE(), -- last updated
vaea_n_3 = ROUND((vaea_n_12 + vaea_n_18) * CAST(jn.jn_our_ref AS FLOAT),2) -- product price
FROM variant_external_analysis
JOIN variant_detail ON vad_id = vaea_vad_id
LEFT JOIN job_number AS JN ON jn_id='20'
WHERE ((vaea_n_3 <> ROUND((vaea_n_12 + vaea_n_18) * CAST(jn.jn_our_ref AS FLOAT),2) -- has price change
OR vaea_n_3 IS NULL) -- Is price field empty
AND vad_variant_code BETWEEN 1000 AND 990000 -- product range for client
这意味着您不会对每行进行2个其他查询。
答案 1 :(得分:0)
这三个项目中的一种可能性是任何:NULL
:
vaea_n_12
vaea_n_18
此子查询:
SELECT CAST(jn_our_ref AS FLOAT) FROM job_number WHERE jn_id='20'
如果即使其中只有一个是NULL
,则整个ROUND()
函数的结果也必须是NULL
,因此{{1} }比较将为vaea_n_3 <> ROUND(...)
。即使FALSE
不是NOT NULL,这也是正确的,现在vaea_n_3
条件的两面都失败了。
为帮助解决此问题,建议您首先将其编写为OR
查询:
SELECT
然后,您可以查找结果与预期不符的行,并在那里获取数据以说明原因。
答案 2 :(得分:0)
尝试更新您的Where
子句以添加IsNull
:
WHERE (vaea_n_3 <> ROUND((vaea_n_12 + vaea_n_18)
* (SELECT CAST(jn_our_ref AS FLOAT) FROM job_number WHERE jn_id='20'),2))
OR IsNull(vaea_n_3, 0) = 0 )
AND vad_variant_code BETWEEN 1000 AND 990000
我还建议使用float
以外的其他字符,或者转换为money
?