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

需要编写SQL Server查询以返回唯一值的总和(基于一列),sql,sql-server,Sql,Sql Server,我的桌子看起来像这样: Supplier Reference Description Total -------------------------------------------------- smiths BP657869510L NULL 42 smiths BP657869510L NULL 42 smiths BP654669510L No. 5621

我的桌子看起来像这样:

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查询到

  • 返回与每个供应商的交易记录列表,消除基于
    参考
    列的重复条目
  • 返回与每个供应商的交易总额,再次根据
    参考
    列消除重复条目
因此,基于上述数据,我想要返回的结果是

    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
列包含相同的值,其他列中的值也可能不同。如果出现这种情况并不重要,我只关心包含不同或唯一的
引用值的行。

请尝试下面的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()将满足此请求()

查看所有字段

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
;

根据OP中的注释,
对于
参考
,总计
始终是相同的,但是
说明
可以更改
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

据我所知,仅使用distinct(如在第一个响应中)返回任何列都是distinct的所有行。例如,如果描述稍有不同,它将返回引用相同的行。我只想要引用不同的行。抱歉-在其他列包含不同值的2行或更多行中,引用可能相同。对于只返回引用不同的行的查询有何建议?就我而言,如果
引用
相同,则
总计
将是相同的。
Description
可能不同。谢谢,我曾想过从您的初始查询中删除
Description
,但理想情况下,我希望返回
Description
列以及其他列,以回答我的第一个问题。我发现,如果一个组有多个唯一的
Description
值,那么您使用该规则进行的查询将为
Description
返回NULL-在这些情况下,有没有办法准确地返回
Description
值而不是返回NULL?谢谢,我不得不对这个问题稍作调整,但这让我找到了第二个问题的答案(即交易总额)。这是一个有效的查询:选择distinct x.supplier,SUM(x.total)OVER(按x.supplier划分)作为total from(选择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我的答案如何LOL.杜德我至少应该投赞成票,mohan111正在使用my@tempdata查询LOL。此查询返回任何列包含不同数据的所有行。它将返回多行,其中
引用
相同,例如,如果每行中的
说明
略有不同。我只想返回
Reference
值不同的行。@james此查询提供第一个和第二个问题所需的结果。你能通过添加更多的数据样本来进一步描述这个问题吗?同时,请更新您所需的数据结果。谢谢,但是如果您将我的上表中的
说明
的一个值更改为唯一值,您的查询将不会返回我上面描述的结果。请检查我的更新,结果有两个史密斯,因为它们具有不同的说明。请编辑您的问题的结果数据。目前这是误导,你的解释令人困惑。每个
供应商是否可以有不同的
参考
?如果有不同的
参考
具有相同的
总数
,您是否仍然只想考虑一行?如果
描述
不同,随机选择哪一个?是的,每个
供应商
可能有不同的
参考
——我通过将
供应商
“smiths”的条目放置在我的样本表中,并使用不同的
参考
条目来证明这一点。我希望每一行都有一个唯一的
参考
,无论金额是否相同。如果
说明
参考
相同的行中不同,我没有选择哪一行的首选项,但理想情况下我希望返回其中一行。@james请更新第二个问题的结果数据。atm它误导了第二个问题的结果数据的正确解读。我想要与每个
供应商
With dValue AS (
  SELECT DISTINCT 
         Supplier
       , Reference
       , Total
  FROM   myTable
)
SELECT Supplier
     , SUM(Total) Total
FROM   dValue
GROUP BY Supplier
SELECT Supplier
     , SUM(Total) Total
FROM   (SELECT DISTINCT Supplier, Reference, Total
        FROM   myTable) dValue
GROUP BY Supplier