基于3个字段的记录在一个表中的某些记录的总和

时间:2013-07-31 07:37:35

标签: sql

看了一眼,也许问错了方法,但找不到我想要的相关问题。

我有一个包含4个字段的表,一个用于另一个记录的ID,然后是成本类型,补充类型和金额。

需要能够通过其中一个ID的补充类型之一添加两个成本类型的金额字段。

PCM_ID  COST_TYPE       SUPPLEMENT_TYPE    AMOUNT
-----------------------------------------------------
2238    AGENT           SS                 85.785
2238    DBCOST          SS                77.9891
2238    DBCOST_TAX      SS                 7.7989
2238    DBSELL          SS                 85.785
2238    DBSELL_TAX      SS                 8.5785
2238    PCCOM_TAX       SS                      0
2238    PCMUP_TAX       SS                      0
2238    RETAIL          SS                 85.785

所以去为SS Supplement添加DBCOST和DBCOST_TAX。

我只是不知道如何进入查询以获得上述每个PCM_ID的值。

我的SQL技能非常有限,基本上都是自学成才,所以这就是我到目前为止所做的。

SELECT SUM (pcs.amount)
  FROM dbo.PCS 
  JOIN dbo.pcm ON pcm.pcm_id = PCS.PCM_ID 
 WHERE pcs.pcm_id = pcm.pcm_id
   and pcs.supplement_type = 'SS'
   AND pcs.cost_type IN ('DBCOST','DBCOST_TAX')

这是一个更大的查询的一部分,但只是遇到了这个部分的问题。

希望这里有足够的信息可以帮助我。

添加到8月10日,

以下是我需要的脚本,少了几个直接数据字段。

Select 
   ID=pcm.pcm_id,
   Name=pcm.name,
   Half_TW_Cost=(SELECT round (SUM(ppc.pax_tw),2) FROM dbo.ppp 
       JOIN dbo.ppc ON ppp.ppp_id = ppc.ppp_id 
       WHERE pcp.pcp_id = ppp.pcp_id AND ppc.cost_type IN ('DBCOST','DBCOST_TAX')),
   Half_TW_Sell=(SELECT round (SUM(ppc.pax_tw),2) FROM dbo.ppp 
       JOIN dbo.ppc ON ppp.ppp_id = ppc.ppp_id 
       WHERE pcp.pcp_id = ppp.pcp_id AND ppc.cost_type IN     
       ('AGENT','DBSELL_TAX','PCMUP_TAX','PCCOM_TAX')),
   SS_Cost=(SELECT round (SUM (pcs.amount),2) FROM dbo.PCS 
       JOIN dbo.pcm ON pcm.pcm_id = PCS.PCM_ID 
       WHERE pcs.pcm_id = pcm.pcm_id AND pcs.supplement_type = 'SS' AND pcs.cost_type 
       IN ('DBCOST','DBCOST_TAX')),
   Range_Seq=pcp.seq,
   Pax_Range=pcp.pxno
FROM  dbo.pcm 
LEFT JOIN dbo.pcp ON pcp.pcm_id = pcm.pcm_id 
where pcm.pcm_id = 2238
group by PCM.PCM_ID, pcm.NAME, pcp.PCP_ID, pcp.SEQ, pcp.PXNO 

我得到的结果如下:

ID     Name                   Half_TW_Cost Half_TW_Sell  SS_Cost      Range_Seq  Pax_Range
-----------------------------------------------------------------------------------------
2238   Brett test PCM Output  106.1200     117.5300      546913.1800  1          10
2238   Brett test PCM Output  99.7200      110.2400      546913.1800  2          15
2238   Brett test PCM Output  96.2400      106.2700      546913.1800  3          20
2238   Brett test PCM Output  94.1500      103.8900      546913.1800  4          25
2238   Brett test PCM Output  88.5900      102.3000      546913.1800  5          30
2238   Brett test PCM Output  92.6100      103.2300      546913.1800  6          2

SS_Cost的值是表的总和,而不是PCM_ID的值。我之后的值是85.79,这是DBCOST + DBCOST_TAX。我知道它是上面的代理值,但这不包括此记录上的任何标记,所以这将改变所以我真的需要DBCOST和TAX。此外,我无法计算税收,因为有些服务没有税,所以它并不总是10%。 任何帮助只是为了让SS_Cost成为单个PCM的值,我们将不胜感激。

3 个答案:

答案 0 :(得分:1)

让我解释一下我的解决方案。

grouped_pcm_sums 这可能是一个视图。 SQL 2008支持CTE,这是我在这里使用的。我喜欢分开一个问题,而不是在一个查询中解决。这里只是获取您要查找的确切数据的总和,并在报告查询中引用正确的ID。

如果你只想2238这样的话我不确定你的帖子,但如果这里的想法不管你报道的是什么PCM_ID,那么总是报告2238的SS总和。然后你可以取消注释注释行并用交叉应用交换连接,以便将值与报告的其余部分进行重新整理。

grouped_sell_values,grouped_cost_values 这些可能是视图。如果我注意到了,你可以从pcp表上的这些子查询链接回你的outter查询。相反,您应该能够在这些单独的操作中按照该pcp_id进行分组,然后再加入它们。

左连接如果您只想要存在关系的行,则可能不需要左连接并且可以省略left。由于您已在其他地方执行了分组,因此不再需要对其他字段进行分组,只是为了将它们放入您的select子句中。您可以随意添加信息字段和后续数据连接。只需注意行数,以确保其他连接不会意外地挤压您的结果。

最后我最后四舍五入。检查拼写错误并单独测试每个CTE以验证它们是否产生正确的结果。通过在较小的块中使用它,您可以解决更简单的SQL而不是一个非常大的SQL。

with grouped_pcm_sums as (
  select pcm_id -- ss_pcm_id
        ,sum(amount) amount
    from PCS
   where COST_TYPE in ('DBCOST','DBCOST_TAX')
     and SUPPLEMENT_TYPE = 'SS'
     --and pcm_id = 2238
   group by pcm_id
), grouped_sell_values as (
  select pcp.pcp_id,sum(ppc.pax_tw) half_tw_sell
    from ppp 
    join ppc on ppp.ppp_id = ppc.ppp_id
    join pcp on ppp.pcp_id = pcp.pcp_id
   where ppc.cost_type in ('AGENT','DBSELL_TAX','PCMUP_TAX','PCCOM_TAX')
   group by pcp.pcp_id
), grouped_cost_values as (
  select pcp.pcp_id,sum(ppc.pax_tw) half_tw_cost
    from ppp 
    join ppc on ppp.ppp_id = ppc.ppp_id 
    join pcp on ppp.pcp_id = pcp.pcp_id
   where ppc.cost_type in ('DBCOST','DBCOST_TAX')
   group by pcp.pcp_id
)
select pcm.pcm_id
      --,ss.ss_pcm_id
      ,pcm.name
      ,round(cost.half_tw_cost,2) half_tw_cost
      ,round(sell.half_tw_sell,2) half_tw_sell
      ,round(ss.amount,2) ss_cost
      ,pcp.seq
      ,pcp.pxno
  from pcm pcm
  -- for only SS 2238 sums, swap left join with the following cross apply
  -- cross apply grouped_pcm_sums ss
  left join grouped_pcm_sums ss on pcm.pcm_id = ss.pcm_id
  left join pcp on pcm.pcm_id = pcp.pcm_id
  left join grouped_sell_values sell on pcp.pcp_id = sell.pcp_id
  left join grouped_cost_values cost on pcp.pcp_id = cost.pcp_id

答案 1 :(得分:0)

也许这就是你要找的东西:

(SELECT
    PCS.PCM_ID, SUM (pcs.amount)
FROM
    dbo.PCS 
    JOIN
    dbo.pcm ON pcm.pcm_id = PCS.PCM_ID 
WHERE
    pcs.pcm_id = pcm.pcm_id
    AND
    pcs.supplement_type = 'SS'
    AND
    pcs.cost_type IN ('DBCOST','DBCOST_TAX')
GROUP BY
    PCS.PCM_ID)

我希望这会有所帮助:)

编辑(16.Aug)
我创建了以下代码,从上面的语句中复制并执行时没有错误(它没有数据,但这不重要)

DECLARE @pcm TABLE(pcm_id INT IDENTITY(1,1), name NVARCHAR(MAX))
DECLARE @pcp TABLE(pcp_id INT IDENTITY(1,1), pcm_id INT, seq NVARCHAR(MAX), pxno NVARCHAR(MAX))
DECLARE @ppc TABLE(ppc_id INT IDENTITY(1,1), ppp_id INT, cost_type NVARCHAR(MAX), pax_tw FLOAT)
DECLARE @ppp TABLE(ppp_id INT IDENTITY(1,1), pcp_id INT)
DECLARE @pcs TABLE(ppc_id INT IDENTITY(1,1), pcm_id INT, ppp_id INT, cost_type NVARCHAR(MAX), supplement_type NVARCHAR(MAX), amount FLOAT)

SELECT 
    ID=pcm.pcm_id, Name=pcm.name,
    Half_TW_Cost=
    (
        SELECT
            ROUND(SUM(ppc.pax_tw), 2)
        FROM
            @ppp AS ppp
            JOIN
            @ppc AS ppc ON ppp.ppp_id = ppc.ppp_id 
        WHERE
            pcp.pcp_id = ppp.pcp_id 
            AND
            ppc.cost_type IN ('DBCOST', 'DBCOST_TAX')
    ),
    Half_TW_Sell=
    (
        SELECT 
            ROUND(SUM(ppc.pax_tw), 2)
        FROM 
            @ppp AS ppp
            JOIN 
            @ppc AS ppc ON ppp.ppp_id = ppc.ppp_id 
        WHERE
            pcp.pcp_id = ppp.pcp_id 
            AND 
            ppc.cost_type IN ('AGENT', 'DBSELL_TAX', 'PCMUP_TAX', 'PCCOM_TAX')
    ),
    SS_Cost=
    (
        SELECT 
            ROUND(SUM(pcs.amount), 2) 
        FROM 
            @pcs AS pcs
            JOIN
            @pcm AS pcm ON pcm.pcm_id = pcs.pcm_id 
        WHERE
            pcs.pcm_id = pcm.pcm_id 
            AND 
            pcs.supplement_type = 'SS' 
            AND 
            pcs.cost_type IN ('DBCOST','DBCOST_TAX')
    ),
    Range_Seq=pcp.seq, Pax_Range=pcp.pxno
FROM 
    @pcm AS pcm
    LEFT JOIN 
    @pcp AS pcp ON pcp.pcm_id = pcm.pcm_id 
WHERE 
    pcm.pcm_id = 2238
GROUP BY 
    pcm.pcm_id, pcm.name, pcp.pcp_id, pcp.seq, pcp.pxno

如果没有为您运行,您使用的是哪个数据库(包括版本)?

答案 2 :(得分:0)

根本不存储税额?看起来这只是成本的10%,那么为什么不在报告时计算它呢?