我在SQL Server 2005中使用以下查询返回了以下结果。现在,我想添加一个业务规则。如果partnumber有一个与之关联的工厂,并且它不是我当前没有检查的工厂,那么它应该列为零。
对于xample,在以下结果中,工厂 - 部件号组合96-ABC应该将总和返回为零。但是11-DEF组合应该继续显示为50.而所有其他值应该返回与现在相同的结果。
如何修改此查询?虽然我试过几个小时,但还没有达成解决方案。
解释:对于下面突出显示的行,partnumber为ABC。但是该部分与工厂“96”没有任何关系,因为你可以看到MHL和MMHP表中的数据......(这与DEF情景类似)....但是partnumber与其他plants
(20和21)有关联 - 因此该部分有restricted association
,它应该显示为植物“96”的零 ....对于DEF部分,所有植物都是OPEN association
- 因此所有行项目的总和应该是SumQty(即现在显示的50)
注意:我们可以在一个查询中获取它吗?分成两个查询并进行更新对我不起作用。
当前结果
数据
DECLARE @MHL TABLE (LineNumber VarCHAR(5), PartNumber VARCHAR(10), Qty INT)
INSERT INTO @MHL VALUES ('10001','ABC',10)
INSERT INTO @MHL VALUES ('10002','ABC',100)
INSERT INTO @MHL VALUES ('10003','DEF',50)
INSERT INTO @MHL VALUES ('10005','KXY',25)
INSERT INTO @MHL VALUES ('10006','KXY',30)
DECLARE @MHP TABLE (PlantCode VarCHAR(5), LineNumber VARCHAR(5))
INSERT INTO @MHP VALUES ('20','10001')
INSERT INTO @MHP VALUES ('21','10002')
INSERT INTO @MHP VALUES ('80','10005')
INSERT INTO @MHP VALUES ('80','10006')
DECLARE @MasterPLantParts TABLE (PlantCode VarCHAR(5), PartNumber VARCHAR(10))
INSERT INTO @MasterPLantParts VALUES ('20','ABC')
INSERT INTO @MasterPLantParts VALUES ('21','ABC')
INSERT INTO @MasterPLantParts VALUES ('96','ABC')
INSERT INTO @MasterPLantParts VALUES ('11','DEF')
INSERT INTO @MasterPLantParts VALUES ('80','KXY')
选择查询
select
mpp.PlantCode PlantCode,
mpp.PartNumber PartNumber,
sum(MHL.Qty) as SumQty
from @MasterPLantParts mpp
left outer join @MHP MHP
on mpp.PlantCode = MHP.PlantCode
inner join @MHL MHL
on (
MHL.LineNumber = MHP.LineNumber
or (
mpp.PartNumber = MHL.PartNumber
and MHP.LineNumber is null
)
)
group by mpp.PlantCode, mpp.PartNumber
order by mpp.PlantCode, mpp.PartNumber
答案 0 :(得分:1)
我认为这可能是你想要的,你需要分步进行......
select mpp.PlantCode PlantCode, mpp.PartNumber PartNumber, sum(IsNull(mhl.Qty,0)) as Qty
into #tt
from @MasterPLantParts mpp
left join @MHP MHP on mpp.PlantCode = MHP.PlantCode
left join @MHL mhl on (mhl.PartNumber = mpp.PartNumber and mhl.LineNumber = mhp.LineNumber)
group by mpp.PlantCode, mpp.PartNumber
order by mpp.PlantCode, mpp.PartNumber
update tt
set Qty = mhl.Qty
FROM #tt tt
inner join @MHL mhl on (mhl.PartNumber = tt.PartNumber)
where tt.Qty=0
and not exists (select 1 from @MasterPLantParts mpp where mpp.PlantCode<>tt.PlantCode and mpp.PartNumber=tt.PartNumber)
select * from #tt
drop table #tt
这会产生......
PlantCode PartNumber SumQty
20 ABC 10
21 ABC 100
96 ABC 0
11 DEF 50
80 KXY 55
作为单个选择语句,可以按如下方式完成......
select mpp.PlantCode PlantCode, mpp.PartNumber PartNumber, Sum(case mhl2.RecCount
when 1 then mhl2.Qty
ELSE IsNull(mhl.Qty,0) END) as Qty
from @MasterPLantParts mpp
left join @MHP MHP on mpp.PlantCode = MHP.PlantCode
left join @MHL mhl on (mhl.PartNumber = mpp.PartNumber and mhl.LineNumber = mhp.LineNumber)
left join (select PartNumber, count(1) RecCount, Sum(Qty) as Qty
from @MHL
group by PartNumber
having count(1)=1) mhl2 on (mhl2.PartNumber = mpp.PartNumber)
group by mpp.PlantCode, mpp.PartNumber
答案 1 :(得分:1)
以下查询可以获得所需的结果。首先,选择MasterPLantParts中的所有行(使用LEFT OUTER JOIN)。然后,用MHL进行连接。如果给定工厂的MHP中没有条目,则选择MHL的所有生产线。
使用MHP中可用的不同部件制作额外的LEFT OUTER JOIN(mhl_parts)。如果某个部件在MHP中根本不可用,那么总和将根据所有线路的MHL计算。否则,它将为零。
select
mpp.PlantCode PlantCode,
mpp.PartNumber PartNumber,
sum(case
when (MHP.LineNumber is null and mhl_parts.PartNumber is null) or
(MHP.LineNumber is not null and mhl_parts.PartNumber is not null)
then MHL.Qty
else 0
end) SumQty
from MasterPLantParts mpp
left outer join MHP on mpp.PlantCode = MHP.PlantCode
left outer join
(
select DISTINCT MHL.PartNumber PartNumber
from MHL
INNER JOIN MHP ON MHP.LineNumber = MHL.LineNumber
) mhl_parts
on mhl_parts.PartNumber = mpp.PartNumber
inner join MHL on MHL.LineNumber = MHP.LineNumber or (mpp.PartNumber = MHL.PartNumber and MHP.LineNumber is null)
group by mpp.PlantCode, mpp.PartNumber
order by mpp.PlantCode, mpp.PartNumber;
Oracle 8i语法:
select
mpp.PlantCode PlantCode,
mpp.PartNumber PartNumber,
sum(case
when (MHP.LineNumber is null and mhl_parts.PartNumber is null) or
(MHP.LineNumber is not null and mhl_parts.PartNumber is not null)
then MHL.Qty
else 0
end) SumQty
from MasterPLantParts mpp, MHP, MHL,
(
select DISTINCT MHL.PartNumber PartNumber
from MHL
INNER JOIN MHP ON MHP.LineNumber = MHL.LineNumber
) mhl_parts
where mpp.PlantCode = MHP.PlantCode(+)
and mpp.PartNumber = mhl_parts.PartNumber(+)
and (MHL.LineNumber = MHP.LineNumber or (mpp.PartNumber = MHL.PartNumber and MHP.LineNumber is null))
group by mpp.PlantCode, mpp.PartNumber
order by mpp.PlantCode, mpp.PartNumber;
答案 2 :(得分:1)
这是一个查询。 我改变了这个逻辑。
首先,我从MHP和MHL表中收集数据,计算数据总和。
然后加入他们。
;WITH twoInOne AS (
SELECT MHP.PlantCode, MHL.PartNumber, SUM(MHL.Qty) AS Qty
FROM @MHL AS MHL
LEFT JOIN @MHP AS MHP
ON MHL.LineNumber = MHP.LineNumber
GROUP BY MHP.PlantCode, MHL.PartNumber
)
SELECT
mpp.PlantCode PlantCode,
mpp.PartNumber PartNumber,
CASE
WHEN tIO.PlantCode IS NOT NULL THEN tIO.Qty
WHEN tIO2.PlantCode IS NULL AND tIO2.PartNumber IS NOT NULL THEN tIO2.Qty
ELSE 0
END
FROM @MasterPLantParts mpp
LEFT JOIN twoInOne AS tIO
ON mpp.PlantCode = tIO.PlantCode
AND tIO.PlantCode IS NOT NULL
LEFT JOIN twoInOne AS tIO2
ON mpp.PartNumber = tIO2.PartNumber
AND tIO2.PlantCode IS NULL
order by mpp.PlantCode, mpp.PartNumber
我不了解甲骨文,但我想这可能是这样的:
SELECT
mpp.PlantCode PlantCode,
mpp.PartNumber PartNumber,
CASE
WHEN tIO.PlantCode IS NOT NULL THEN tIO.Qty
WHEN tIO2.PlantCode IS NULL AND tIO2.PartNumber IS NOT NULL THEN tIO2.Qty
ELSE 0
END
FROM @MasterPLantParts mpp,
(SELECT MHP.PlantCode, MHL.PartNumber, SUM(MHL.Qty) AS Qty
FROM @MHL MHL, @MHP MHP
WHERE MHL.LineNumber = MHP.LineNumber(+)
GROUP BY MHP.PlantCode, MHL.PartNumber
) tIO,
(SELECT MHP.PlantCode, MHL.PartNumber, SUM(MHL.Qty) AS Qty
FROM @MHL MHL, @MHP MHP
WHERE MHL.LineNumber = MHP.LineNumber(+)
GROUP BY MHP.PlantCode, MHL.PartNumber
) tIO2
WHERE mpp.PlantCode = tIO.PlantCode(+)
AND mpp.PartNumber = tIO2.PartNumber(+)
AND tIO.PlantCode IS NOT NULL
AND tIO2.PlantCode IS NULL
order by mpp.PlantCode, mpp.PartNumber
答案 3 :(得分:-2)
警告:未经测试,可能效率不高 - sqlfiddle无法正常工作
select mpp.PlantCode PlantCode,
mpp.PartNumber PartNumber,
nvl(sum(MHL.Qty),0) as SumQty -- edit1: add nvl
from @MasterPLantParts mpp
left outer join @MHP MHP on mpp.PlantCode = MHP.PlantCode
left join @MHL MHL on ( -- edit2: from inner join to left join
MHL.LineNumber = MHP.LineNumber
or (
mpp.PartNumber = MHL.PartNumber
and mpp.PartNumber not in (
select MHL2.PartNumber
from @MHL MHL2
inner join @MHP mhp2 on MHL2.LineNumber = MHP2.LineNumber
where mhp2.PlantCode != mpp.PlantCode
)
)
)
group by mpp.PlantCode, mpp.PartNumber
order by mpp.PlantCode, mpp.PartNumber