Reputation: 686
Suppose we have a table:
╔═════════════════════════════════════╗
║ Name Date Value ║
╠═════════════════════════════════════╣
║ John 2013-01-01 10:20:00 10 ║
║ John 2013-01-01 12:20:11 20 ║
║ Mark 2013-01-01 11:44:10 10 ║
║ Mark 2013-01-02 12:00:00 20 ║
║ Mark 2013-01-03 15:20:00 20 ║
║ Tim 2013-01-01 15:11:12 5 ║
║ Tim 2013-01-03 18:44:44 10 ║
║ Tim 2013-01-03 20:11:00 15 ║
╚═════════════════════════════════════╝
And using a single SELECT
query, output:
╔════════════════════════════════════════════════╗
║ Name 2013-01-01 2013-01-02 2013-01-03 ║
╠════════════════════════════════════════════════╣
║ John 30 0 0 ║
║ Mark 10 20 20 ║
║ Tim 5 0 25 ║
╚════════════════════════════════════════════════╝
How do you do this in a single SELECT
? I tried with SUM(DISTINCT)
but no success. I cannot figure out the logic.
It must be GROUP BY Name
only (I think), but how would I compute the SUM()
by intervals?
Upvotes: 1
Views: 1580
Reputation: 33
Try this:
DECLARE @cols AS NVARCHAR(MAX)
,@query AS NVARCHAR(MAX)
SELECT @cols = STUFF((
SELECT ',' + QUOTENAME(CAST(DATE as DATE))
FROM (
SELECT DISTINCT CAST(DATE as DATE) DATE FROM #YourTable
) tbl
ORDER BY DATE
FOR XML PATH('')
,TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '');
SET @query =
'WITH CTE (
NAME
,DATE
,VALUE
)
AS (
SELECT NAME
,CAST(DATE AS DATE)
,Cast(Value AS INT)
FROM #YourTable
)
SELECT NAME
,' + @cols + '
FROM CTE
PIVOT(SUM(Value) FOR DATE IN (' + @cols + ')) PVT;'
EXECUTE (@query);
Upvotes: 0
Reputation: 1230
SELECT NAME,
ISNULL([2013-01-01],0) [2013-01-01],
ISNULL([2013-01-02],0) [2013-01-02],
ISNULL([2013-01-03],0) [2013-01-03]
FROM (
SELECT NAME, CONVERT(DATE, [Date]) [Date], SUM([Value]) [Value]
FROM TABLE1
GROUP BY NAME, CONVERT(DATE, [Date])
) src
PIVOT (
SUM([Value])
FOR [Date]
IN ( [2013-01-01], [2013-01-02], [2013-01-03])
) pvt
The date columns may have to be specified differently, depending on how they would print out.
SQL Authority Pivot Example
My SQL Fiddle Example
Upvotes: 2
Reputation: 70638
If the dates are fixed:
SELECT [Name],
SUM(CASE WHEN [Date] >= '20130101'
AND [Date] < '20130102' THEN Value END) [2013-01-01],
SUM(CASE WHEN [Date] >= '20130102'
AND [Date] < '20130103' THEN Value END) [2013-01-02],
SUM(CASE WHEN [Date] >= '20130103'
AND [Date] < '20130104' THEN Value END) [2013-01-03]
FROM YourTable
GROUP BY [Name]
Upvotes: 3
Reputation: 4137
Try this:
SELECT NAME,
SUM(CASE
WHEN CAST(DATE AS DATE) = '2013-01-01' THEN VALUE
ELSE 0
END) [2013-01-01],
SUM(CASE
WHEN CAST(DATE AS DATE) = '2013-01-02' THEN VALUE
ELSE 0
END) [2013-01-02],
SUM(CASE
WHEN CAST(DATE AS DATE) = '2013-01-03' THEN VALUE
ELSE 0
END) [2013-01-03]
FROM TABLE1
GROUP BY NAME
Take a look at the working example on SQL Fiddle.
Upvotes: 3