SQL:SELECT DISTINCT 未返回不同的值
SQL: SELECT DISTINCT not returning distinct values
下面的代码应该 return 子查询 lp_num 字段中的唯一记录,然后在外部查询中使用,但我仍然得到 [=24= 的倍数] 场地。一个ReferenceNumber可以有多个ApptDate记录,但是每个lp_num只能有1个rf_num。这就是为什么我试图在子查询中一直检索唯一的 lp_num 记录,但它不起作用。我正在使用 Report Builder 3.0。
当前输出
所需的输出是在 lp_num 字段中只有唯一的记录。这是因为 lp_num 字段中的每个值都是一个托盘,一个托盘。右边的信息是它到达的时间 (ApptDate) 以及交货的参考编号 (ref_num)。因此,一个托盘有多个收货日期是没有意义的...它只能到达一次...
SELECT DISTINCT
dbo.ISW_LPTrans.item,
dbo.ISW_LPTrans.lot,
dbo.ISW_LPTrans.trans_type,
dbo.ISW_LPTrans.lp_num,
dbo.ISW_LPTrans.ref_num,
(MIN(CONVERT(VARCHAR(10),dbo.CW_CheckInOut.ApptDate,101))) as appt_date_only,
dbo.CW_CheckInOut.ApptTime,
dbo.item.description,
dbo.item.u_m,
dbo.ISW_LPTrans.qty,
(CASE
WHEN dbo.ISW_LPTrans.trans_type = 'F'
THEN 'Produced internally'
ELSE
(CASE
WHEN dbo.ISW_LPTrans.trans_type = 'R'
THEN 'Received from outside'
END)
END
) as original_source
FROM
dbo.ISW_LPTrans
INNER JOIN dbo.CW_Dock_Schedule ON LTRIM(RTRIM(dbo.ISW_LPTrans.ref_num)) = dbo.CW_Dock_Schedule.ReferenceNumber
INNER JOIN dbo.CW_CheckInOut ON dbo.CW_CheckInOut.TruckID = dbo.CW_Dock_Schedule.TruckID
INNER JOIN dbo.item ON dbo.item.item = dbo.ISW_LPTrans.item
WHERE
(dbo.ISW_LPTrans.trans_type = 'R') AND
--CONVERT(VARCHAR(10),dbo.CW_CheckInOut.ApptDate,101) <= CONVERT(VARCHAR(10),dbo.ISW_LPTrans.trans_date,101) AND
dbo.ISW_LPTrans.lp_num IN
(SELECT DISTINCT
dbo.ISW_LPTrans.lp_num
FROM
dbo.ISW_LPTrans
INNER JOIN dbo.item ON dbo.ISW_LPTrans.item = dbo.item.item
INNER JOIN dbo.job ON dbo.ISW_LPTrans.ref_num = dbo.job.job AND dbo.ISW_LPTrans.ref_line_suf = dbo.job.suffix
WHERE
(dbo.ISW_LPTrans.trans_type = 'W' OR dbo.ISW_LPTrans.trans_type = 'I') AND
dbo.ISW_LPTrans.ref_num IN
(SELECT
dbo.ISW_LPTrans.ref_num
FROM
dbo.ISW_LPTrans
--INNER JOIN dbo.ISW_LPTrans on dbo.ISW_LPTrans.
WHERE
dbo.ISW_LPTrans.item LIKE @item AND
dbo.ISW_LPTrans.lot LIKE @lot AND
dbo.ISW_LPTrans.trans_type = 'F'
GROUP BY
dbo.ISW_LPTrans.ref_num
) AND
dbo.ISW_LPTrans.ref_line_suf IN
(SELECT
dbo.ISW_LPTrans.ref_line_suf
FROM
dbo.ISW_LPTrans
--INNER JOIN dbo.ISW_LPTrans on dbo.ISW_LPTrans.
WHERE
dbo.ISW_LPTrans.item LIKE @item AND
dbo.ISW_LPTrans.lot LIKE @lot AND
dbo.ISW_LPTrans.trans_type = 'F'
GROUP BY
dbo.ISW_LPTrans.ref_line_suf
)
GROUP BY
dbo.ISW_LPTrans.lp_num
HAVING
SUM(dbo.ISW_LPTrans.qty) < 0
)
GROUP BY
dbo.ISW_LPTrans.item,
dbo.ISW_LPTrans.lot,
dbo.ISW_LPTrans.trans_type,
dbo.ISW_LPTrans.lp_num,
dbo.ISW_LPTrans.ref_num,
dbo.CW_CheckInOut.ApptDate,
dbo.CW_CheckInOut.ApptTime,
dbo.item.description,
dbo.item.u_m,
dbo.ISW_LPTrans.qty
ORDER BY
dbo.ISW_LPTrans.lp_num
简而言之 - 从 SQL 的角度来看,您使用 DISTINCT
的方式在逻辑上是错误的。
您的 DISTINCT
在 WHERE
子句的 IN
子查询中 - 在代码的那个点它绝对没有效果(除了性能损失)。想一想 - 如果外部查询 returns dbo.ISW_LPTrans.lp_num
的非唯一值(发生这种情况很明显)这些值仍然可以在 IN
子查询的不同值内 - IN
不强制执行一对一匹配,它只强制执行外部查询值在内部值内的事实,但它们可以匹配多次。所以这绝对不是DISTINCT
的错。
我将执行以下检查步骤:
- 查看外部
FROM
部分中是否存在导致数据乘法的 JOIN ON
条件 不足(例如,如果 table 在几个列上有主键到外键的关系,但你只加入其中一个等等)。
- 检查哪些来源包含外部
FROM
部分中的非不同记录 - 然后清理您的来源,或调整 JOIN 条件和/或WHERE 子句,以便您只选择不同且正确的记录。事实上,您可能需要在 FROM
部分中 SELECT DISTINCT
- 那里会更有意义。
下面的代码应该 return 子查询 lp_num 字段中的唯一记录,然后在外部查询中使用,但我仍然得到 [=24= 的倍数] 场地。一个ReferenceNumber可以有多个ApptDate记录,但是每个lp_num只能有1个rf_num。这就是为什么我试图在子查询中一直检索唯一的 lp_num 记录,但它不起作用。我正在使用 Report Builder 3.0。
当前输出
所需的输出是在 lp_num 字段中只有唯一的记录。这是因为 lp_num 字段中的每个值都是一个托盘,一个托盘。右边的信息是它到达的时间 (ApptDate) 以及交货的参考编号 (ref_num)。因此,一个托盘有多个收货日期是没有意义的...它只能到达一次...
SELECT DISTINCT
dbo.ISW_LPTrans.item,
dbo.ISW_LPTrans.lot,
dbo.ISW_LPTrans.trans_type,
dbo.ISW_LPTrans.lp_num,
dbo.ISW_LPTrans.ref_num,
(MIN(CONVERT(VARCHAR(10),dbo.CW_CheckInOut.ApptDate,101))) as appt_date_only,
dbo.CW_CheckInOut.ApptTime,
dbo.item.description,
dbo.item.u_m,
dbo.ISW_LPTrans.qty,
(CASE
WHEN dbo.ISW_LPTrans.trans_type = 'F'
THEN 'Produced internally'
ELSE
(CASE
WHEN dbo.ISW_LPTrans.trans_type = 'R'
THEN 'Received from outside'
END)
END
) as original_source
FROM
dbo.ISW_LPTrans
INNER JOIN dbo.CW_Dock_Schedule ON LTRIM(RTRIM(dbo.ISW_LPTrans.ref_num)) = dbo.CW_Dock_Schedule.ReferenceNumber
INNER JOIN dbo.CW_CheckInOut ON dbo.CW_CheckInOut.TruckID = dbo.CW_Dock_Schedule.TruckID
INNER JOIN dbo.item ON dbo.item.item = dbo.ISW_LPTrans.item
WHERE
(dbo.ISW_LPTrans.trans_type = 'R') AND
--CONVERT(VARCHAR(10),dbo.CW_CheckInOut.ApptDate,101) <= CONVERT(VARCHAR(10),dbo.ISW_LPTrans.trans_date,101) AND
dbo.ISW_LPTrans.lp_num IN
(SELECT DISTINCT
dbo.ISW_LPTrans.lp_num
FROM
dbo.ISW_LPTrans
INNER JOIN dbo.item ON dbo.ISW_LPTrans.item = dbo.item.item
INNER JOIN dbo.job ON dbo.ISW_LPTrans.ref_num = dbo.job.job AND dbo.ISW_LPTrans.ref_line_suf = dbo.job.suffix
WHERE
(dbo.ISW_LPTrans.trans_type = 'W' OR dbo.ISW_LPTrans.trans_type = 'I') AND
dbo.ISW_LPTrans.ref_num IN
(SELECT
dbo.ISW_LPTrans.ref_num
FROM
dbo.ISW_LPTrans
--INNER JOIN dbo.ISW_LPTrans on dbo.ISW_LPTrans.
WHERE
dbo.ISW_LPTrans.item LIKE @item AND
dbo.ISW_LPTrans.lot LIKE @lot AND
dbo.ISW_LPTrans.trans_type = 'F'
GROUP BY
dbo.ISW_LPTrans.ref_num
) AND
dbo.ISW_LPTrans.ref_line_suf IN
(SELECT
dbo.ISW_LPTrans.ref_line_suf
FROM
dbo.ISW_LPTrans
--INNER JOIN dbo.ISW_LPTrans on dbo.ISW_LPTrans.
WHERE
dbo.ISW_LPTrans.item LIKE @item AND
dbo.ISW_LPTrans.lot LIKE @lot AND
dbo.ISW_LPTrans.trans_type = 'F'
GROUP BY
dbo.ISW_LPTrans.ref_line_suf
)
GROUP BY
dbo.ISW_LPTrans.lp_num
HAVING
SUM(dbo.ISW_LPTrans.qty) < 0
)
GROUP BY
dbo.ISW_LPTrans.item,
dbo.ISW_LPTrans.lot,
dbo.ISW_LPTrans.trans_type,
dbo.ISW_LPTrans.lp_num,
dbo.ISW_LPTrans.ref_num,
dbo.CW_CheckInOut.ApptDate,
dbo.CW_CheckInOut.ApptTime,
dbo.item.description,
dbo.item.u_m,
dbo.ISW_LPTrans.qty
ORDER BY
dbo.ISW_LPTrans.lp_num
简而言之 - 从 SQL 的角度来看,您使用 DISTINCT
的方式在逻辑上是错误的。
您的 DISTINCT
在 WHERE
子句的 IN
子查询中 - 在代码的那个点它绝对没有效果(除了性能损失)。想一想 - 如果外部查询 returns dbo.ISW_LPTrans.lp_num
的非唯一值(发生这种情况很明显)这些值仍然可以在 IN
子查询的不同值内 - IN
不强制执行一对一匹配,它只强制执行外部查询值在内部值内的事实,但它们可以匹配多次。所以这绝对不是DISTINCT
的错。
我将执行以下检查步骤:
- 查看外部
FROM
部分中是否存在导致数据乘法的JOIN ON
条件 不足(例如,如果 table 在几个列上有主键到外键的关系,但你只加入其中一个等等)。 - 检查哪些来源包含外部
FROM
部分中的非不同记录 - 然后清理您的来源,或调整 JOIN 条件和/或WHERE 子句,以便您只选择不同且正确的记录。事实上,您可能需要在FROM
部分中SELECT DISTINCT
- 那里会更有意义。