我尝试过使用distinct关键字,我尝试对列进行分组,但查询仍会返回重复的结果。
SELECT
distinct orderformdump.itemno,
case when PRH.ACTIVE = 1 and PRH.STARTDATE < cast(GETDATE() as DATE) and (PRH.ENDDATE IS NULL OR PRH.ENDDATE >= cast(GETDATE() as DATE)) then CAST(1 AS BIT) ELSE CAST(0 AS BIT) END as isindeal
FROM ORDERFORMDUMP
INNER JOIN ICITEM ON ICITEM.FMTITEMNO = orderformdump.itemno
LEFT JOIN PRD2 on ICITEM.ITEMNO = PRD2.ITEMNO
LEFT JOIN PRH on PRD2.CODE = PRH.CODE
order by Itemno
重复是由加入,LEFT JOIN PRD2 on ICITEM.ITEMNO = PRD2.ITEMNO
或列case when PRH.ACTIVE = 1 and PRH.STARTDATE < cast(GETDATE() as DATE) and (PRH.ENDDATE IS NULL OR PRH.ENDDATE >= cast(GETDATE() as DATE)) then CAST(1 AS BIT) ELSE CAST(0 AS BIT) END as isindeal
引起的。我可以删除连接并使用子查询获得相同的结果,但子查询会导致查询运行得非常慢(即使我将列编入索引)。
为什么会有多个结果,我该怎么做才能解决这个问题?
答案 0 :(得分:1)
试试这个:
SELECT distinct orderformdump.itemno, isnull(tmp.isindeal, CAST(0 AS BIT) ) isindeal
FROM ORDERFORMDUMP
INNER JOIN ICITEM ON ICITEM.FMTITEMNO = orderformdump.itemno
outer apply
(
select top 1 CAST(1 AS BIT) as isindeal
from PRD2 INNER JOIN PRH on PRD2.CODE = PRH.CODE
where ICITEM.ITEMNO = PRD2.ITEMNO and PRH.ACTIVE = 1
and cast(GETDATE() as DATE) between PRH.STARTDATE and isnull(PRH.ENDDATE, cast(GETDATE() as DATE))
) tmp
答案 1 :(得分:1)
要查找问题行,请尝试:
SELECT itemNo, count(*) as dealCount
FROM (
SELECT
distinct orderformdump.itemno,
case when PRH.ACTIVE = 1 and PRH.STARTDATE < cast(GETDATE() as DATE) and (PRH.ENDDATE IS NULL OR PRH.ENDDATE >= cast(GETDATE() as DATE)) then CAST(1 AS BIT) ELSE CAST(0 AS BIT) END as isindeal
FROM ORDERFORMDUMP
INNER JOIN ICITEM ON ICITEM.FMTITEMNO = orderformdump.itemno
LEFT JOIN PRD2 on ICITEM.ITEMNO = PRD2.ITEMNO
LEFT JOIN PRH on PRD2.CODE = PRH.CODE
) t
GROUP BY itemNO
ORDER BY dealCount DESC
任何与dealCount和gt; 1表示ICITEM,PRD1或PRH中的多行。然后你应该能够找出你需要消除的东西。
您加入的表格中有多少行?您可以通过稍微更改JOIN来加快速度。你是LEFT JOIN到LEFT JOIN,你并没有真正使用它。由于您只使用PRH.ACTIVE,PRH.STARTDATE和PRH.ENDDATE,因此您可以INNER JOIN PRH到PRD2并减少您左转加入ICITEM的结果集。然后,我猜你的STARTDATE和ENDDATE是DATE数据类型而不是datetime(将getDate()强制转换为DATE)。如果它们是日期时间,您可能需要考虑时间组件。对于你的isindeal,你不需要将1和0作为位。如果您需要显示真或假,只需返回它们并在代码中处理它们。