仅当表中没有其他相关条目时才获取总和

时间:2014-06-19 14:43:42

标签: sql sql-server

我在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)

注意:我们可以在一个查询中获取它吗?分成两个查询并进行更新对我不起作用。

当前结果

enter image description here

数据

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

4 个答案:

答案 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;

SQL Fiddle

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