我有一个查询,需要更新另一个表的一些元组,我只需要更新两个记录,每个记录对应的值是从另一个表中获取的,目前我的查询工作正常,没有错别字,没有错误,但是提取了零条记录并因此获取了其他表',我发现我的内部子查询无法获取相关数据,但是我无法测试我的内部子查询,因为它需要引用两个表
这是查询
UPDATE SALARY_DETAIL_TBL sd
SET GROSS_EARNING =(SELECT AMOUNT FROM SALARY_DETAIL_REPORT sr WHERE sd.EMP_ID = sr.EMP_ID AND sr.PAY_CODE = 997) ,
GROSS_DEDUCTION =
(SELECT AMOUNT
FROM SALARY_DETAIL_REPORT sr
WHERE sd.EMP_ID = sr.EMP_ID
AND sr.PAY_CODE = 998
)
WHERE (GROSS_EARNING IS NULL
OR GROSS_DEDUCTION IS NULL)
由内部查询填充的GROSS_EARNING
和GROSS_DEDUCTION
列,该内部查询产生零结果,我想分别进行测试,请为我提供最佳解决方案。
现在它会抛出
UPDATE SALARY_DETAIL_TBL sd
SET GROSS_EARNING =(SELECT AMOUNT FROM SALARY_DETAIL_REPORT sr WHERE sd.EMP_ID = sr.EMP_ID AND sr.PAY_CODE = 997) ,
GROSS_DEDUCTION =
(SELECT AMOUNT
FROM SALARY_DETAIL_REPORT sr
WHERE sd.EMP_ID = sr.EMP_ID
AND sr.PAY_CODE = 998
)
WHERE (GROSS_EARNING IS NULL
OR GROSS_DEDUCTION IS NULL)
BadSqlGrammerException: single-row subquery returns more than one row
答案 0 :(得分:3)
您可以通过查询检查表中是否存在数据
SELECT AMOUNT
FROM SALARY_DETAIL_REPORT sr
WHERE sr.EMP_ID in(select EMP_ID
from SALARY_DETAIL_TBL sd
where (GROSS_EARNING IS NULL
OR GROSS_DEDUCTION IS NULL)
)
AND sr.PAY_CODE in (997,998)
答案 1 :(得分:1)
您有两项任务:
GROSS_EARNING =
(SELECT AMOUNT FROM SALARY_DETAIL_REPORT sr
WHERE sd.EMP_ID = sr.EMP_ID AND sr.PAY_CODE = 997)
和
GROSS_DEDUCTION =
(SELECT AMOUNT FROM SALARY_DETAIL_REPORT sr
WHERE sd.EMP_ID = sr.EMP_ID AND sr.PAY_CODE = 998)
,您希望两者最多返回一行。
因此,检查每个EMP_ID
是否有PAY_CODE
个具有多个匹配项:
select emp_id, pay_code, count(*)
from salary_detail_report
where pay_code in (997, 998)
group by emp_id, pay_code
having count(*) > 1;
答案 2 :(得分:0)
您可以使用以下命令检查是否存在未引用的数据
SELECT AMOUNT
FROM SALARY_DETAIL_REPORT sr
WHERE sr.EMP_ID not in(select EMP_ID
from SALARY_DETAIL_TBL sd
where (GROSS_EARNING IS NULL
OR GROSS_DEDUCTION IS NULL)
)
AND sr.PAY_CODE in (997,998)
答案 3 :(得分:0)
好吧,看来您有多行具有相同的emp_id和相同的pay_code。 您应该首先检查是否正确,如果是,则定义一个策略来选择哪个是更新另一个表的正确方法,否则只需删除错误的行即可。 例如,如果行中有某个日期,则可以按该日期排序,并将结果限制为1。
(SELECT AMOUNT
FROM SALARY_DETAIL_REPORT sr
WHERE sd.EMP_ID = sr.EMP_ID
AND sr.PAY_CODE = 998
ORDER BY sr.some_column_that_makes_sense
FETCH FIRST 1 ROWS ONLY)