需要编写SQL Server查询以返回唯一值的总和(基于一列)

时间:2014-05-06 22:17:36

标签: sql sql-server

我的表格如下:

Supplier    Reference       Description      Total    
--------------------------------------------------
smiths      BP657869510L    NULL             42
smiths      BP657869510L    NULL             42
smiths      BP654669510L    No. 5621         13
smiths      BP654669510L    No. 5621         13
corrigan    15:51           Order 23542      23
corrigan    15:51           Order 23542      23
williams    14015           Block B          19
williams    14015           Block B          19

我想写一个T-SQL查询到

  • 返回与每个供应商的交易清单,根据Reference列消除重复的条目。
  • 返回与每个供应商的交易总额,再次根据Reference列消除重复的条目。

所以我想根据上面的数据返回的结果是

    Supplier    Reference       Description      Total    
    ---------------------------------------------------
    smiths      BP657869510L    NULL             42
    smiths      BP654669510L    No. 5621         13
    corrigan    15:51           Order 23542      23
    williams    14015           Block B          19

和第二个要求:

    Supplier    Total  
    ---------------------  
    smiths      55
    corrigan    23
    williams    19

这可能吗?请注意,即使Reference列包含相同的值,其他列中的值也可能不同。如果发生这种情况并不重要,我只关心包含不同或唯一Reference值的行。

3 个答案:

答案 0 :(得分:1)

declare @tempData table
(
    supplier nvarchar(20),
    reference nvarchar (20),
    xDescription nvarchar(20),
    total int
);

insert into @tempData
select 'smiths',      'BP657869510L'    ,NULL,             42 union all
select 'smiths',      'BP657869510L'    ,NULL,             42 union all
select 'smiths',      'BP654669510L'    ,'No. 5621',         13 union all
select 'smiths',      'BP654669510L'    ,'No. 5621',         13 union all
select 'corrigan',    '15:51'           ,'Order 23542',      23 union all
select 'corrigan',    '15:51'           ,'Order 23542',      23 union all
select 'williams',    '14015'           ,'Block B',          19 union all
select 'williams',    '14015'           ,'Block B',          19
;

select distinct x.supplier,
SUM(X.total)OVER(PARTITION BY x.supplier )As Total from 
(Select a.supplier,a.reference,a.xDescription,a.total from @tempData a
GROUP BY a.supplier,a.reference,a.xDescription,a.total) X 
GROUP BY x.supplier,X.total

答案 1 :(得分:1)

根据OP Total的评论,Reference的评论始终相同,但Description可能会发生变化。 DISTINCT相当于GROUP BY

中所有列的SELECT

要获得第一个要求,如果可以删除Description

,那就足够了
SELECT DISTINCT 
       Supplier
     , Reference
     , Total
FROM   myTable

如果不可能,则可以在同一行上执行NULL,MAX或其他内容,在下面的查询中,如果组中有多个值,则返回NULL,否则输出单个值

SELECT Supplier
     , Reference
     , Description = CASE WHEN COUNT(DISTINCT Description) > 1 THEN NULL
                          ELSE MAX(Description)
                     END
     , Total
FROM   myTable
GROUP BY Supplier, Reference, Total

要获得第二个,上面的查询可以用作添加CTE的主查询的GROUP BY,在这种情况下,不需要Description列,因此会丢弃

With dValue AS (
  SELECT DISTINCT 
         Supplier
       , Reference
       , Total
  FROM   myTable
)
SELECT Supplier
     , SUM(Total) Total
FROM   dValue
GROUP BY Supplier

如果您的SQLServer版本中CTE不可用,则可以将第一个查询用作子查询以获得相同的结果

SELECT Supplier
     , SUM(Total) Total
FROM   (SELECT DISTINCT Supplier, Reference, Total
        FROM   myTable) dValue
GROUP BY Supplier

答案 2 :(得分:0)

尝试下面的sql
假设@tempData是你的表名。

declare @tempData table
(
    supplier nvarchar(20),
    reference nvarchar (20),
    xDescription nvarchar(20),
    total int
);

insert into @tempData
select 'smiths',      'BP657869510L'    ,NULL,             42 union all
select 'smiths',      'BP657869510L'    ,NULL,             42 union all
select 'smiths',      'BP654669510L'    ,'No. 5621',         13 union all
select 'smiths',      'BP654669510L'    ,'No. 5621',         13 union all
select 'corrigan',    '15:51'           ,'Order 23542',      23 union all
select 'corrigan',    '15:51'           ,'Order 23542',      23 union all
select 'williams',    '14015'           ,'Block B',          19 union all
select 'williams',    '14015'           ,'Block B',          19
;

select 
    a.supplier
    , a.reference
    , a.xDescription
    , a.total
from @tempData a
group by a.supplier 
    , a.reference
    , a.xDescription
    , a.total
;

/*
supplier             reference            xDescription         total
-------------------- -------------------- -------------------- -----------
corrigan             15:51                Order 23542          23
smiths               BP654669510L         No. 5621             13
smiths               BP657869510L         NULL                 42
williams             14015                Block B              19
*/


with cte as
(
select 
    a.supplier
    , a.reference
    , a.xDescription
    , a.total
from @tempData a
group by a.supplier 
    , a.reference
    , a.xDescription
    , a.total
) 
select 
    distinct c.supplier, sum(c.total) over(partition by c.supplier) as total
from cte c
;

/*
supplier             total
-------------------- -----------
corrigan             23
smiths               55
williams             19
*/

<强>更新
根据要求,此查询的目的是包括具有相同供应商且具有不同描述的单独记录:示例供应商smith

Dense_Rank()将完成此请求(http://technet.microsoft.com/en-us/library/ms173825(v=sql.90).aspx

with cte as
(
select 
    a.supplier
    , a.reference
    , a.xDescription
    , a.total
    ,dense_rank() over(partition by a.supplier order by a.supplier, a.xDescription) as dRow
from @tempData a
group by a.supplier 
    , a.reference
    , a.xDescription
    , a.total
) 
select 
    distinct c.supplier, sum(c.total) over(partition by c.supplier,drow) as total
from cte c
;

/*
supplier             total
-------------------- -----------
corrigan             23
smiths               13
smiths               42
williams             19
*/

查看所有字段

with cte as
(
select 
    a.supplier
    , a.reference
    , a.xDescription
    , a.total
    ,dense_rank() over(partition by a.supplier order by a.supplier, a.xDescription) as dRow
from @tempData a
group by a.supplier 
    , a.reference
    , a.xDescription
    , a.total
) 
select 
    distinct c.supplier, c.reference,c.xDescription, sum(c.total) over(partition by c.supplier,drow) as total
from cte c
;