根据最大成本总和,从两个表中的一个返回结果

时间:2014-09-07 23:03:15

标签: sql sql-server group-by

我有两张成本表。一组是实际记录的,一组是基于品牌的估计

我想做的是报告更高者。

示例数据是:

ParentTable:

GroupId, TransactionId, Otherinfo..... 123, 4444, ... 530, 2311, ... 201, 1111, ...

ActualData

TransactionId, Product, Cost 4444, 3039, 100 4444, 3002, 4000 2311, 3004, 693

EstimateData

GroupId, Brand, Cost 123, 33, 80 123, 42, 3000 530, 222, 1200 201, 121, 4040

在这种情况下,我想要返回的是一个包含

的表

GroupId, Code, Cost 123, 3039, 100 <- Actual data 123, 3002, 4000 <- Actual data 530, 222, 1200 <- Estimate data 201, 121, 4040 <- Estimate data

目前我正在考虑首先从两个表中进行选择,返回GroupId和Max(成本)。我正在努力如何使用它来返回我想要的结果。

任何人都可以帮助我吗?

编辑在父表中添加..它并没有真正改变一些事情,但可能会对数据提供更多的见解

2 个答案:

答案 0 :(得分:2)

如果我理解正确,您希望从表中选择其总数最大的每一行。 cte包含所有groupId以及最大总数来自哪个表。然后,union使用cte仅选择属于每个表的最大组的行。

with cte as (
    select * from (
        select source, GroupId,
        row_number() over (partition by GroupId order by total_cost desc) rn
        from (
            select 'ad' source, GroupId, sum(Cost) total_cost
            from ActualData ad
            group by GroupId
            union all
            select 'ed' source, GroupId, sum(Cost) total_cost
            from EstimatedData ed
            group by GroupId
        ) t1
    ) t1 where rn = 1
)

select GroupId, Product Code, Cost from ActualData ad
where GroupId in (select GroupId from cte where source = 'ad')
union all
select GroupId, Brand Code, Cost from EstimatedData ed
where GroupId in (select GroupId from cte where source = 'ed')

答案 1 :(得分:0)

这种关系肯定是模糊的,但预期结果

| GROUPID | CODE | COST |
|---------|------|------|
|     123 | 3039 |  100 |
|     123 | 3002 | 4000 |
|     201 |  121 | 4040 |
|     530 |  222 | 1200 |

是由此查询生成的:

WITH
    acte AS (
                  SELECT p.GroupId, ad.Product, ad.Cost
                       , SUM(ad.cost) OVER (PARTITION BY Groupid) AS grp_cost
                  FROM ActualData AS ad
                        INNER JOIN parenttable p ON ad.TransactionId = p.TransactionId
            ),
   ecte AS (
                  SELECT GroupId, Brand, SUM(Cost) AS cost
                  FROM EstimateData
                  GROUP BY
                        GroupId
                      , Brand
            )
SELECT acte.GroupId, acte.Product AS Code, acte.Cost
FROM acte
WHERE NOT EXISTS (
            SELECT
                  NULL
            FROM ecte
            WHERE ecte.GroupId = acte.GroupId
                  AND ecte.cost > acte.grp_cost
      )
UNION ALL
      SELECT ecte.GroupId, ecte.Brand AS Code, ecte.Cost
      FROM ecte
      WHERE NOT EXISTS (
                  SELECT
                        NULL
                  FROM acte
                  WHERE acte.GroupId = ecte.GroupId
                        AND acte.grp_cost > ecte.cost
            )
;

See this SQLfiddle demo