2013-07-30 37 views
1

我对SQL很陌生,所以如果我错过了显而易见的道歉,请提前致歉。SQL按客户分组时选择第一个价格

我的数据由客户合同号,服务日期和价格清单组成。我需要能够按客户分组,按服务日期拉第一个价格,在另一个列中有所有价格的总和。

所以我有这样的:

SELECT 
CONTRACT, 
SUM(PRICES) as [TOTAL SPENT] 
FIRST(PRICE) as [FIRST PRICE] 
FROM TABLE 
GROUP BY CONTRACT 
ORDER BY CONTRACT 

但显然首先是没有一个内置的函数名(我使用Microsoft SQL Server)。有什么建议么?

在此先感谢!

+1

你能提供sql来创建必要的表/字段吗? – Robadob

+0

请问什么版本的SQL Server? –

+0

你说“按服务日期拉第一个价格”...但服务日期不在检索中选择...所以哪个价格是“第一个”?示例数据和期望的输出将很高兴见到 –

回答

1

尝试:

-- @tmp represents your table 
    declare @tmp table (
    [Contract] int, 
    [Prices] decimal(18,5), 
    [ServiceDate] datetime 
    ) 

    -- some testing data - you may skip that 
    insert into @tmp values(1, 100, '2011-01-01') 
    insert into @tmp values(1, 200, '2011-01-02') 
    insert into @tmp values(2, 10, '2011-01-01') 
    insert into @tmp values(2, 20, '2011-01-02') 
    insert into @tmp values(2, 30, '2011-01-03') 


    SELECT 
     [CONTRACT], 
     SUM(PRICES) as [TOTAL SPENT], 
     (SELECT TOP 1 t2.PRICES FROM @tmp t2 
     WHERE t2.[Contract] = t1.[Contract] 
     ORDER BY [SERVICEDATE]) as [FIRST PRICE] 
    FROM @tmp t1 
    GROUP BY [CONTRACT] 
    ORDER BY [CONTRACT] 
2

您可以使用ROW_NUMBER

WITH CTE AS(
    SELECT CONTRACT, 
      SUM(PRICES) OVER(PARTITION BY CONTRACT) as [TOTAL SPENT], 
      PRICE as [FIRST PRICE], 
      ROW_NUMBER()OVER(PARTITION BY Contract Order By ServiceDate) 
    FROM TABLE 
) 
SELECT CONTRACT, [TOTAL SPENT], [FIRST PRICE] 
FROM CTE 
WHERE RN = 1 
ORDER BY CONTRACT 

这从各合约组根据ServiceDate挑选的第一行。这种方法的优点是您可以选择所有列而无需使用聚合函数或将其包含在GROUP BY中。请注意,您至少需要SQLServer的2005年

0

事情是这样的:

SELECT 
    CONTRACT, 
    SUM(PRICE) as [TOTAL SPENT], 
    (SELECT TOP 1 PRICE FROM [TABLE] 
    WHERE CONTRACT_DATE = MIN(T.CONTRACT_DATE) 
    AND CONTRACT = T.CONTRACT) AS [FIRST PRICE] 
    FROM [TABLE] T 
    GROUP BY CONTRACT 
    ORDER BY CONTRACT 

SQL Fiddle demo

+0

如果有重复项,该怎么办?相关的子查询至少需要TOP 1--尽管我不认为这将是最有效的方法。 –

+0

@AaronBertrand不错的地方,我在写作的时候考虑过'TOP 1',但是忘了添加它 - 现在编辑回答。至于效率,这在实践中不太可能成为问题,除非有大量的数据(并且在另一篇文章中建议使用子查询中的'MIN'确实比'ORDER BY'更有效)。 –

+0

嗯,这真的取决于。如果有一个索引来支持它,那么在很多情况下,使用该顺序生成row_number比在每行中扫描MIN要高效得多。 –