基于多个项目在子查询中计算

时间:2014-10-31 20:36:35

标签: sql sql-server sql-server-2008 sql-server-2005 sql-server-2012

Sql Server 2008

我有几张Stock表,数据如下

移交入境:

 Item_ID    Barcode ITEM_CODE   Cp_Id   whLocId dt_added    COLOUR_ID   MRN_NO
-----------------------------------------------------------------------------
 123456 222222  62626262    1   78  2014-10-31 23:04:02.920 2   99897
 123456 222222  62626262    1   78  2014-10-30 23:04:11.340 2   99897
 123456 222222  62626262    1   78  2014-07-23 23:04:16.273 2   99897
 123456 222222  62626262    1   78  2014-10-21 23:04:19.327 2   99897
 123456 222222  1234         1  74  2014-11-01 00:16:42.783 1   99897
 123456 222222  1234         1  74  2014-10-24 00:16:53.447 1   99897
 123456 222222  1234         1  74  2014-10-23 00:16:55.467 1   99897
 123456 222222  1234         1  74  2014-10-23 00:17:00.283 2   99897
 123456 222222  1234         1  74  2014-10-23 00:17:02.080 2   99897
 123456 222222  1234         1  70  2014-10-23 00:17:10.273 2   99897
 123456 222222  12348        1  70  2014-10-23 00:17:14.080 2   99897
 123456 222222  12348        1  78  2014-10-24 00:18:37.340 2   99897
 123456 222222  62626262    2   78  2014-10-24 00:24:38.977 2   99897

OUTWARD:

 Item_ID    Barcode ITEM_CODE   Cp_Id   whLocId dt_added    COLOUR_ID   PO_NO
-----------------------------------------------------------------------------
  123456    222222  62626262    1   78  2014-10-20 23:04:58.487 2   99897
  123456    222222  62626262    1   78  2014-10-30 23:05:04.863 2   99897
  123456    222222  12348   1   70  2014-10-26 00:17:39.780 2   99897
  123456    222222  12348   1   78  2014-10-26 00:18:19.903 2   99897

BLOCK:

 Item_ID    Barcode ITEM_CODE   Cp_Id   whLocId dt_added    COLOUR_ID   PO_NO
-----------------------------------------------------------------------------
  123456    222222  62626262    1   78  2014-10-31 23:03:43.923 2   99897
  123456    222222  1234    1   74  2014-11-01 00:16:24.490 1   99897

我正在尝试生成一个基于ITEM_CODE,COLOUR_ID等的关闭报告

我尝试了下面的逻辑,但它为每个项目填充相同的输出。

`SELECT
p.ITEM_CODE  as ITEM_CODE,
--(select COUNT(*) from inward where cast(dt_added as DATE)<>CAST(GETDATE() as DATE)  group by item_code,whlocid )- (select COUNT(*) from outward where cast(dt_added as DATE)<>CAST(GETDATE() as DATE)and item_code='62626262' and colour_ID='2' group by item_code,whlocid)as Opening_Stock,
(select COUNT(*) from inward where cast(dt_added as DATE)=CAST(GETDATE() as DATE) ) as DAY_INWARD_Stock,
(select COUNT(*) from inward ) as 'TOTAL_INWARD_Stock',
(select COUNT(*) from OUTWARD where cast(dt_added as DATE)=CAST(GETDATE() as DATE) ) as DAY_OUTWARD_Stock,
(select COUNT(*) from OUTWARD ) as TOTAL_OUTWARD_Stock,
--((select COUNT(*) from inward )-(select COUNT(*) from outward )) as TOTAL_AVAILABLE_STOCK,
(select COUNT(*) from BLOCK where cast(dt_added as DATE)=CAST(GETDATE() as DATE) )as DAY_BLOCK_Stock,
(select COUNT(*) from BLOCK ) as TOTAL_BLOCK_Stock,
p.cp_id,
p.whLocId,
p.COLOUR_ID
from inward  p 

left join outward out
on p.item_code=out.item_code
left join block blo
on p.item_code=blo.item_code
group by p.item_code,p.cp_id,p.colour_id,p.whlocid`

但它显示所有项目的相同值。

结果:

 ITEM_CODE  DAY_INWARD_Stock    TOTAL_INWARD_Stock  DAY_OUTWARD_Stock TOTAL_OUTWARD_Stock   DAY_BLOCK_Stock TOTAL_BLOCK_Stock   cp_id   whLocId COLOUR_ID
-----------------------------------------------------------------------------
1234    1   13  0   4   1   2   1   74  1
1234    1   13  0   4   1   2   1   70  2
1234    1   13  0   4   1   2   1   74  2
12348   1   13  0   4   1   2   1   70  2
12348   1   13  0   4   1   2   1   78  2
62626262    1   13  0   4   1   2   1   78  2
62626262    1   13  0   4   1   2   2   78  2

这有利于被封锁2天希望问题的Machha很清楚,现在格式很好

由于

**试过这个但它的隔离基于ITEM CODE而不是cp_id,colour_id,whlocid **

`SELECT
p.ITEM_CODE  as ITEM_CODE,
--(select COUNT(*) from inward where cast(dt_added as DATE)<>CAST(GETDATE() as DATE)  group by item_code,whlocid )- (select COUNT(*) from outward where cast(dt_added as DATE)<>CAST(GETDATE() as DATE)and item_code='62626262' and colour_ID='2' group by item_code,whlocid)as Opening_Stock,
(select COUNT(*) from inward where cast(dt_added as DATE)=CAST(GETDATE() as DATE) and item_code=p.item_code ) as DAY_INWARD_Stock,
(select COUNT(*) from inward where item_code=p.item_code) as 'TOTAL_INWARD_Stock',
(select COUNT(*) from OUTWARD where cast(dt_added as DATE)=CAST(GETDATE() as DATE)and item_code=p.item_code ) as DAY_OUTWARD_Stock,
(select COUNT(*) from OUTWARD where item_code=p.item_code ) as TOTAL_OUTWARD_Stock,
--((select COUNT(*) from inward )-(select COUNT(*) from outward )) as TOTAL_AVAILABLE_STOCK,
(select COUNT(*) from BLOCK where cast(dt_added as DATE)=CAST(GETDATE() as DATE)and item_code=p.item_code )as DAY_BLOCK_Stock,
(select COUNT(*) from BLOCK where item_code=p.item_code) as TOTAL_BLOCK_Stock,
p.cp_id,
p.whLocId,
p.COLOUR_ID
from inward  p 
left join outward out
on p.item_code=out.item_code
left join block blo
on p.item_code=blo.item_code
group by p.item_code,p.cp_id,p.colour_id,p.whlocid`

结果:

 ITEM_CODE  DAY_INWARD_Stock    TOTAL_INWARD_Stock  DAY_OUTWARD_Stock TOTAL_OUTWARD_Stock   DAY_BLOCK_Stock TOTAL_BLOCK_Stock   cp_id   whLocId COLOUR_ID
-----------------------------------------------------------------------------
1234    1   6   0   0   1   1   1   74  1
1234    1   6   0   0   1   1   1   70  2
1234    1   6   0   0   1   1   1   74  2
12348   0   2   0   2   0   0   1   70  2
12348   0   2   0   2   0   0   1   78  2
62626262    0   5   0   2   0   1   1   78  2
62626262    0   5   0   2   0   1   2   78  2


`SELECT
p.ITEM_CODE  as ITEM_CODE,
(select COUNT(*) from inward where cast(dt_added as DATE)<>CAST(GETDATE() as DATE)  and item_code=p.item_code and cp_id=p.cp_id and colour_id=p.colour_id and whlocid=p.whlocid  )- (select COUNT(*) from outward where cast(dt_added as DATE)<>CAST(GETDATE() as DATE) and item_code=p.item_code and cp_id=p.cp_id and colour_id=p.colour_id and whlocid=p.whlocid)as Opening_Stock,
(select COUNT(*) from inward where cast(dt_added as DATE)=CAST(GETDATE() as DATE) and item_code=p.item_code and cp_id=p.cp_id and colour_id=p.colour_id and whlocid=p.whlocid ) as DAY_INWARD_Stock,
(select COUNT(*) from inward where item_code=p.item_code and cp_id=p.cp_id and colour_id=p.colour_id and whlocid=p.whlocid) as 'TOTAL_INWARD_Stock',
(select COUNT(*) from OUTWARD where cast(dt_added as DATE)=CAST(GETDATE() as DATE)and item_code=p.item_code and cp_id=p.cp_id and colour_id=p.colour_id and whlocid=p.whlocid ) as DAY_OUTWARD_Stock,
(select COUNT(*) from OUTWARD where item_code=p.item_code and cp_id=p.cp_id and colour_id=p.colour_id and whlocid=p.whlocid) as TOTAL_OUTWARD_Stock,
((select COUNT(*) from inward where item_code=p.item_code and cp_id=p.cp_id and colour_id=p.colour_id and whlocid=p.whlocid)-(select COUNT(*) from outward where item_code=p.item_code and cp_id=p.cp_id and colour_id=p.colour_id and whlocid=p.whlocid  )) as TOTAL_AVAILABLE_STOCK,
(select COUNT(*) from BLOCK where cast(dt_added as DATE)=CAST(GETDATE() as DATE)and item_code=p.item_code and cp_id=p.cp_id and colour_id=p.colour_id and whlocid=p.whlocid)as DAY_BLOCK_Stock,
(select COUNT(*) from BLOCK where item_code=p.item_code) as TOTAL_BLOCK_Stock,
p.cp_id,
p.whLocId,
p.COLOUR_ID
from inward  p 
left join outward out
on p.item_code=out.item_code
left join block blo
on p.item_code=blo.item_code
group by p.item_code,p.cp_id,p.colour_id,p.whlocid`

似乎这个工作正在发挥..但任何其他简单或表现良好的方法都会非常有用

2 个答案:

答案 0 :(得分:0)

`SELECT
p.ITEM_CODE  as ITEM_CODE,
(select COUNT(*) from inward where cast(dt_added as DATE)<>CAST(GETDATE() as DATE)  and item_code=p.item_code and cp_id=p.cp_id and colour_id=p.colour_id and whlocid=p.whlocid  )- (select COUNT(*) from outward where cast(dt_added as DATE)<>CAST(GETDATE() as DATE) and item_code=p.item_code and cp_id=p.cp_id and colour_id=p.colour_id and whlocid=p.whlocid)as Opening_Stock,
(select COUNT(*) from inward where cast(dt_added as DATE)=CAST(GETDATE() as DATE) and item_code=p.item_code and cp_id=p.cp_id and colour_id=p.colour_id and whlocid=p.whlocid ) as DAY_INWARD_Stock,
(select COUNT(*) from inward where item_code=p.item_code and cp_id=p.cp_id and colour_id=p.colour_id and whlocid=p.whlocid) as 'TOTAL_INWARD_Stock',
(select COUNT(*) from OUTWARD where cast(dt_added as DATE)=CAST(GETDATE() as DATE)and item_code=p.item_code and cp_id=p.cp_id and colour_id=p.colour_id and whlocid=p.whlocid ) as DAY_OUTWARD_Stock,
(select COUNT(*) from OUTWARD where item_code=p.item_code and cp_id=p.cp_id and colour_id=p.colour_id and whlocid=p.whlocid) as TOTAL_OUTWARD_Stock,
((select COUNT(*) from inward where item_code=p.item_code and cp_id=p.cp_id and colour_id=p.colour_id and whlocid=p.whlocid)-(select COUNT(*) from outward where item_code=p.item_code and cp_id=p.cp_id and colour_id=p.colour_id and whlocid=p.whlocid  )) as TOTAL_AVAILABLE_STOCK,
(select COUNT(*) from BLOCK where cast(dt_added as DATE)=CAST(GETDATE() as DATE)and item_code=p.item_code and cp_id=p.cp_id and colour_id=p.colour_id and whlocid=p.whlocid)as DAY_BLOCK_Stock,
(select COUNT(*) from BLOCK where item_code=p.item_code) as TOTAL_BLOCK_Stock,
p.cp_id,
p.whLocId,
p.COLOUR_ID
from inward  p 

left join outward out
on p.item_code=out.item_code
left join block blo
on p.item_code=blo.item_code
group by p.item_code,p.cp_id,p.colour_id,p.whlocid`

答案 1 :(得分:0)

您的查询产生错误结果的原因是,无论您的加入条件如何,都会执行计数。看看这一节:

(select COUNT(*) from OUTWARD 
        where cast(dt_added as DATE)=CAST(GETDATE() as DATE) ) as DAY_OUTWARD_Stock,
(select COUNT(*) from OUTWARD ) as TOTAL_OUTWARD_Stock,

这不是说“嘿我需要确保我正确地映射到我的项目代码和颜色”,毕竟它甚至知道它的范围没有达到主要查询。最重要的是,它甚至没有选择那些变量。它只知道它的数量。那么,需要做些什么。

第1步:我们需要稍微简化此查询。真的没有必要这些疯狂的选择。 Count将忽略空值,我们可以通过我们想要的ID开始正确地将事物分组。

SELECT p.ITEM_CODE  as ITEM_CODE,
    COUNT(p.dt_added) as DAY_INWARD_Stock,
    Null as 'TOTAL_INWARD_Stock',
    COUNT(out.dt_added ) as DAY_OUTWARD_Stock,
    Null as TOTAL_OUTWARD_Stock,
    COUNT(blo.dt_added) as DAY_BLOCK_Stock,
    Null as TOTAL_BLOCK_Stock,
    p.cp_id,
    p.whLocId,
    p.COLOUR_ID
from inward  p 
    left join outward out
        on p.item_code=out.item_code
    left join block blo
        on p.item_code=blo.item_code
where cast(p.dt_added as DATE) = CAST(GETDATE() as DATE)
    Or (cast(out.dt_added as DATE) = CAST(GETDATE() as DATE)
        Or out.dt_added Is Null)
    Or (cast(blo.dt_added as DATE) = CAST(GETDATE() as DATE)
        Or blo.dt_added Is Null)
group by p.item_code,p.cp_id,p.colour_id,p.whlocid

请注意,我删除了总数。这有助于确保查询的这一半有效。那么他们如何被重新包围? 第2步:这是我们启动子查询的地方。我们通过添加3个连接来完成此操作,这些连接将代表这些新表。这一半的查询将如下所示:

SELECT p.ITEM_CODE  as ITEM_CODE,
    Null as DAY_INWARD_Stock,
    pCount.pRecords as 'TOTAL_INWARD_Stock',
    Null as DAY_OUTWARD_Stock,
    outCount.outRecords as TOTAL_OUTWARD_Stock,
    Null as DAY_BLOCK_Stock,
    bloCount.bloRecords as TOTAL_BLOCK_Stock,
    p.cp_id,
    p.whLocId,
    p.COLOUR_ID
from inward  p 
    left join (Select ITEM_CODE, Count(ITEM_CODE) As pRecords 
                  from inward 
                  group by ITEM_CODE) As pCount
        on p.item_code = pCount.item_code
    left join (Select inward.ITEM_CODE, Count(inward.ITEM_CODE) As outRecords 
                  from inward 
                      inner Join outward on inward.ITEM_CODE = outward.ITEM_CODE
                  group by ITEM_CODE) As outCount
        on p.item_code = outCount.item_code
    left join (Select inward.ITEM_CODE, Count(inward.ITEM_CODE) As bloRecords 
                  from inward 
                      inner Join block on inward.ITEM_CODE = block.ITEM_CODE
                  group by ITEM_CODE) As bloCount
        on p.item_code = bloCount.item_code

注意:到目前为止,我已将这些方法基于我认为您想要实现的目标。您可能会注意到计数按item_code分组。您还会注意到这些子查询中的内部联接。这完全基于您希望这些按item_code分组的假设。如果不这样,那么它是一个不同的查询。另外需要注意的是,这实际上只是按item_code对项目进行分组。我不知道你是否注意到这一点,但你的代码只假设color_id和其他参数是相同的。显然,如果这不是您的意图,则需要更改查询。无论如何,我们现在处于最后一步。

第3步:组合查询的时间。假设上述两个查询都产生了您期望的结果然后将结果组合起来很简单。你最后的查询应该是这样的。

SELECT p.ITEM_CODE  as ITEM_CODE,
    COUNT(p.dt_added) as DAY_INWARD_Stock,
    pCount.pRecords as 'TOTAL_INWARD_Stock',
    COUNT(out.dt_added ) as DAY_OUTWARD_Stock,
    outCount.outRecords as TOTAL_OUTWARD_Stock,
    COUNT(blo.dt_added) as DAY_BLOCK_Stock,
    bloCount.bloRecords as TOTAL_BLOCK_Stock,
    p.cp_id,
    p.whLocId,
    p.COLOUR_ID
from inward  p 
    left join outward out
        on p.item_code=out.item_code
    left join block blo
        on p.item_code=blo.item_code
    left join (Select ITEM_CODE As inItem_CDE, Count(ITEM_CODE) As pRecords 
                  from inward 
                  group by ITEM_CODE) As pCount
        on p.item_code = pCount.inItem_CDE
    left join (Select inward.ITEM_CODE As outItem_CDE, Count(inward.ITEM_CODE) As outRecords 
                  from inward 
                      inner Join outward on inward.ITEM_CODE = outward.ITEM_CODE
                  group by ITEM_CODE) As outCount
        on p.item_code = outCount.outItem_CDE
    left join (Select inward.ITEM_CODE As bloITEM_CDE, Count(inward.ITEM_CODE) As bloRecords 
                  from inward 
                      inner Join block on inward.ITEM_CODE = block.ITEM_CODE
                  group by ITEM_CODE) As bloCount
        on p.item_code = bloCount.bloITEM_CDE
where cast(p.dt_added as DATE) = CAST(GETDATE() as DATE)
    Or (cast(out.dt_added as DATE) = CAST(GETDATE() as DATE)
        Or out.dt_added Is Null)
    Or (cast(blo.dt_added as DATE) = CAST(GETDATE() as DATE)
        Or blo.dt_added Is Null)
group by p.item_code,p.cp_id,p.colour_id,p.whlocid

就是这样。希望现在所有的查询都是正确的,并为您提供所需的结果。