2014-05-06 63 views
0

我的表看起来像这样:需要编写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列包含相同的值,其他列中的值也可能不同。如果发生这种情况并不重要,我只关心包含不同或独特值的行。

+1

是有可能 – cyan

+1

你的解释是混乱。每个'供应商'有可能有不同的参考?如果有不同的'Reference'与'Total'相同,你还想只考虑一行吗?如果“描述”不同,可以随机选择哪一个? – dnoeth

+0

是的,每个'供应商'都可以有不同的'参考' - 我通过在不同'参考'条目下的样品表中为'供应商''史密斯'分配条目来证明这一点。我希望每一行都有一个唯一的'Reference'来考虑数量是否相同。如果'Reference'中的'Description'不同,那么'Reference'是相同的行,我没有偏好选择哪一个,但理想情况下我想返回其中的一个。 – James

回答

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 
*/ 

UPDATE
的请求,该查询的目的是包括具有不同的描述中,相同的供应商独立的记录:例如供应商史密斯

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 
; 
+0

此查询返回任何列包含不同的数据的所有行。例如,如果'Description'在每行中略有不同,它将返回'Reference'的多行。我只想返回参考值不同的行。 – James

+0

@james此查询提供了第一个和第二个问题的结果。您能否通过添加更多数据样本来进一步描述问题?并且还请更新您所需的数据结果。 – cyan

+0

谢谢你,但是如果你在上面的表中将“Description”的一个值改为unique,那么你的查询将不会返回上面描述的结果。 – James

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 
+0

谢谢,我不得不对这个查询做一个小小的调整,但它引导我回答我的第二个问题(即交易总和)。这是工作的查询:select distinct x.supplier, SUM(X.total)OVER(PARTITION BY x.supplier)As Total from (Select a.supplier,a.reference,a.description,a.total from @tempData a GROUP BY a.supplier,a.reference,a.description,a.total)X GROUP BY x.supplier,x.reference,X.total – James

+0

我的答案LOL如何?老兄,我应该至少投票了,mohan111正在使用我的@tempdata查询LOL。 – cyan

1

按照从OP Total评论永远是Reference相同,但Description可以改变。 DISTINCT相当于在SELECT

一个GROUP BY所有列为了得到第一个需求的不同是不够的,如果它能够丢弃Description

SELECT DISTINCT 
     Supplier 
    , Reference 
    , Total 
FROM myTable 

,如果它是不可能的,那么空,一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 
+0

据我所知,仅使用不同的(如在您的第一个响应中)将返回任何列不同的所有行。例如,如果描述稍有不同,它将返回引用相同的行。我只想要引用不同的行。 – James

+0

道歉 - 引用可能在2行或更多行中相同,其他列包含不同的值。任何关于查询的建议只返回Reference不同的行吗? – James

+0

为了我的目的,如果'Reference'是相同的'Total'将是相同的。 “说明”可能不同。 – James