添加列到 select 语句会引入所有历史数据

Adding column to select statement brings in all historical data

大家晚上好!

我 运行遇到一个我很难理解的非常奇怪的问题。

我有 3 tables(零件 table、零件移动历史和零件详细信息 table)。

我想做的是得到结果集 return 批号、零件号、产品描述、数量、零件位置、当前库存(相对于完整历史记录)以及谁最后移动了产品。

现在,进行查询。当我 运行 下面的查询时,我得到了 4,751 行的结果集;这与我的预期结果完全吻合。但是,当我尝试在 userid 字段中添加时,我得到的结果集是 186,573。这个大的结果集似乎提取了所有历史数据,而不是仅仅将用户 ID 与我实际需要的 4,751 行相匹配。

来自 Table 我需要的部分 (prod_desc) 从零件详情 Table 我需要 (lot,part#,lotquantity,prtlocation) 从零件移动历史记录 Table 我需要 (move_date,user_id)

4,751 查询:

SELECT DISTINCT
inv.lot,
inv.part#,
prt.prod_desc,
inv.lotquantity,
inv.prtlocation,
MAX(mv.move_date)AS 'Move Date'
FROM invdet AS inv
LEFT JOIN movetable AS mv ON inv.part# = mv.part#
LEFT JOIN partmstr AS prt ON inv.part# = prt.part#
WHERE inv.lot IS NOT NULL
GROUP BY inv.lot,inv.part#,prt.prod_desc,inv.lotquantity,inv.prtlocation
ORDER BY inv.prtlocation

186,573 查询:

SELECT DISTINCT
inv.lot,
inv.part#,
prt.prod_desc,
inv.lotquantity,
inv.prtlocation,
MAX(mv.move_date)AS 'Move Date'
mv.user_id
FROM invdet AS inv
LEFT JOIN movetable AS mv ON inv.part# = mv.part#
LEFT JOIN partmstr AS prt ON inv.part# = prt.part#
WHERE inv.lot IS NOT NULL
GROUP BY inv.lot,inv.part#,prt.prod_desc,inv.lotquantity,inv.prtlocation,mv.user_id
ORDER BY inv.prtlocation

如果我不使用 MAX 函数,我不会获取当前库存,而是获取我不需要的 table 中的所有结果。我仍在学习,我的 GROUP BY 有很多不足之处,因为我仍在思考它(欢迎提出建议!)。我确定我可以在此处的某个地方放入一个子查询,但我仍在弄清楚这些问题。非常感谢任何帮助!

我认为问题在于,当您从 table movetable 插入 mv.user_id 时,您会得到所有部分的运动,而不仅仅是日期最大的最后一个运动(mv.move_date). 一种方法是删除左连接以移动 table 并可能使用像

这样的交叉应用
SELECT inv.lot,inv.part,prt.prod_desc,inv.lotquantity,inv.prtlocation,x.move_date,x.user_id
FROM invdet AS inv
CROSS APPLY(SELECT TOP 1
             mv.user_id,mv.move_date
            FROM movetable mv
            WHERE inv.part=mv.part
            ORDER BY mv.move_date DESC) AS x
LEFT JOIN partmstr AS prt ON inv.part=prt.part
WHERE inv.lot IS NOT NULL
ORDER BY inv.prtlocation

我没有测试过,但应该没问题,可能有点慢,因为交叉应用在 inv table 中对每一行执行一个子查询。如果太慢,可以用ROWNUMBER创建一个只由最后一个动作组成的table,然后用在LEFT JOIN中,如下

SELECT inv.lot,inv.part,prt.prod_desc,inv.lotquantity,inv.prtlocation,y.move_date,y.user_id
FROM invdet AS inv
LEFT JOIN(SELECT x.user_id,x.move_date,x.part
          FROM (SELECT mv.user_id,mv.move_date,mv.part,rn=ROWNUMBER() OVER(PARTITION BY mv.part ORDER BY mv.move_date DESC)
                FROM movetable mv) AS x
          WHERE x.rn=1) AS y ON y.part=inv.part
LEFT JOIN partmstr AS prt ON inv.part=prt.part
WHERE inv.lot IS NOT NULL
ORDER BY inv.prtlocation

希望对您有所帮助。