The following is how I have created the table:
CREATE TABLE #tmp
(
[Counter] int
,Per date not null
,Cam float
,CamMeg float
,Hfx float
,HfxMet float
,TorMetric float
)
The following is how I call the table later on in my script:
SELECT
((ROW_NUMBER() over(order by Per desc)-1)/#Avg)+1 as [Counter], Per,
Cam,
AVG(CamMetric) as CamMet,
HfxMe,
FROM #tmp
GROUP BY [counter] ;
DROP TABLE #tmp
The following are the errors that I get:
Msg 8120, Level 16, State 1, Line 175
Column '#tmp.Per' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Msg 8120, Level 16, State 1, Line 175
Column '#tmp.Per' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
What am I doing incorrectly?
The data looks like the following
counter --- per ---Cam --- HfxMet ---......
1 2012-02-09 3 16
1 2012-02-24 4 12
1 2012-03-04 2 15
2 2012-03-15 1 18
2 2012-03-30 6 20
2 2012-04-07 10 6
3 2012-04-28 8 3
Now I want to add two more columns called CamMetricAvg and HfxMetric that will look at all counters that are 1 and then get the CamMetric and HfxMetric values respectively and give the average and put that on each Like the following:
counter --- per ---Cam --- CamMt ---
1 2012-02-09 3 3
1 2012-02-24 4 3
1 2012-03-04 2 3
2 2012-03-15 1 5.6
2 2012-03-30 6 5.6
2 2012-04-07 10 5.6
3 2012-04-28 8 8
SELECT [Counter], Period,
CamMetric,
AvgCamMetric = AVG(CamMetric) OVER(PARTITION BY Counter),
HfxMetric,
AvgHfxMetric = AVG(HfxMetric) OVER(PARTITION BY Counter)
... repeat for other metrics ...
FROM #tmpTransHrsData
GROUP BY [Counter], Period, CamMetric, HfxMetric;
SQLFiddle example
Related
I have a set of data that I want to classify into groups based on a prior record id existing on the newer rows. The initial record of the group has a prior sequence id = 0.
The data is as follows:
customer id
sequence id
prior_sequence id
1
1
0
1
2
1
1
3
2
2
4
0
2
5
4
2
6
0
2
7
6
Ideally, I would like to create the following grouping column and yield the following results:
customer id
sequence id
prior sequence id
grouping
1
1
0
1
1
2
1
1
1
3
2
1
2
4
0
2
2
5
4
2
2
6
0
3
2
7
6
3
I've attempted to utilize island gap logic utilizing the ROW_NUMBER() function. However, I have been unsuccessful in doing so. I suspect the need here is more along the lines of a recursive CTE, which I am attempting at the moment.
I agree that a recursive CTE will do the job. Something like:
WITH reccte AS
(
/*query that determines starting point for recursion
*
* In this case we want all records with no prior_sequence_id
*/
SELECT
customer_id,
sequence_id,
prior_sequence_id,
/*establish grouping*/
ROW_NUMBER() OVER (ORDER BY sequence_id) as grouping
FROM yourtable
WHERE prior_sequence_id = 0
UNION
/*join the recursive CTe back to the table and iterate*/
SELECT
yourtable.customer_id,
yourtable.sequence_id,
yourtable.prior_sequence_id,
reccte.grouping
FROM reccte
INNER JOIN yourtable ON reccte.sequence_id = yourtable.prior_sequence_id
)
SELECT * FROM reccte;
It looks like you could use a simple correlated query, at least given your sample data:
select *, (
select Sum(Iif(prior_sequence_id = 0, 1, 0))
from t t2
where t2.sequence_id <= t.sequence_id
) Grouping
from t;
See Example Fiddle
I wish to get the overall ranking of a runner's race time by a particular event.
SELECT a.EventName, b.RunEventName, c.RaceTime, RANK() OVER (ORDER BY RaceTime)Rank
FROM dbo.Event AS a, dbo.RunEvent as b, dbo.RegistrationEvent as c, dbo.Registration as d
WHERE b.EventId = a.EventId
AND c.RunEventId = b.RunEventId
AND c.RegistrationId = d.RegistrationId
AND b.RunEventId = '1'
AND NOT RaceTime IS NULL AND NOT RaceTime = 0
My query results are as shown below:
EventName RunEventName RaceTime Rank
--------------------------------------------------------------
1 Event 1 Run 1049 1
2 Event 1 Run 1179 2
3 Event 1 Run 1407 3
4 Event 1 Run 1648 4
5 Event 1 Run 1817 5
6 Event 1 Run 1865 6
If I do an SQL statement to only display row number 5, my results are:
EventName RunEventName RaceTime Rank
----------------------------------------------------------------
1 Event1 Run 1817 1
The expected output for rank should be 5 but it shows 1 instead.
Use your current query as a CTE, and then select the row you want from the CTE.
WITH cte AS ({your current query})
SELECT * FROM cte
WHERE Rank=5
In SQL Server 2008 R2, I have a table like this:
ID Dates Count
1 03-02-2014 2
2 04-02-2014 1
3 05-02-2014 NULL
4 06-02-2014 1
5 07-02-2014 3
6 08-02-2014 NULL
7 09-02-2014 2
8 10-02-2014 NULL
9 11-02-2014 1
10 12-02-2014 3
11 13-02-2014 NULL
12 14-02-2014 1
I have an INT variable having some value such as #XCount = 15.
My requirement is to update the count column with (#XCount - Count) such as the result of previous record will be subtracted by the Count value in the next record.
Result:
ID Dates Count
1 03-02-2014 13 (15-2)
2 04-02-2014 12 (13-1)
3 05-02-2014 12 (12-0)
4 06-02-2014 11 (12-1)
5 07-02-2014 8 (11-3)
6 08-02-2014 8 (8-0)
7 09-02-2014 6 (8-2)
8 10-02-2014 6 (6-0)
9 11-02-2014 5 (6-1)
10 12-02-2014 2 (5-3)
11 13-02-2014 2 (2-0)
12 14-02-2014 1 (2-1)
I'm reluctant to use cursors as a solution. Can somebody help me?
How about something like
DECLARE #XCount INT = 15
;WITH Vals AS(
SELECT ID, Dates, [Count] OriginalCount, #XCount - ISNULL([COUNT],0) NewCount
FROM Table1
WHERE ID = 1
UNION ALL
SELECT t.ID, t.Dates, t.[Count], v.NewCount - ISNULL(t.[Count],0)
FROM Table1 t INNER JOIN Vals v ON t.ID = v.ID + 1
)
SELECT *
FROM Vals
SQL Fiddle DEMO
Do note thought that this is a recursive query, and that sometimes (until the tech allows for it, such as SQL SERVER 2012 LAG or Running totals) old does work.
How can I add another column that would partition them quarterly (Jan-March, April-June, June-Sep) and then add another counter to keep track of the quarterly and define that Q1 2011 is not the same as Q1 2012. Essentially how would I add the Quarters and Tracker Column. I have looked at ROW_NUMBER(), NTILE functions but not sure how to combine them with months.
--- Period --- Quarters---Tracker
2012-05-06 2 1
2012-05-20 2 1
2012-06-03 2 1
2012-07-01 3 2
2012-08-12 3 2
2012-08-26 3 2
2012-09-09 3 2
2012-10-07 4 3
2012-10-21 4 3
2012-11-04 4 3
2012-11-18 4 3
2012-12-02 4 3
2012-12-16 4 3
2012-12-30 4 3
2013-01-13 1 4
2013-01-27 1 4
REALLY STUCK!
I put the quarter CASE logic in the table definition, but you could also put it in the query so you don't have to modify your table.
Create Table Blah
(
SampleDate Date Default(Convert(Date,Getdate())),
Quarters As ( Case
When Month(SampleDate) Between 1 And 3 Then 1
When Month(SampleDate) Between 4 And 6 Then 2
When Month(SampleDate) Between 7 And 9 Then 3
Else 4 End)
)
Insert Blah (SampleDate)
Select '2012-05-06'
Union All
Select '2012-05-20'
Union All
Select '2012-06-03'
Union All
Select '2012-07-01'
Union All
Select '2012-08-12'
Union All
Select '2012-09-09'
Union All
Select '2012-10-07'
Union All
Select '2012-11-04'
Union All
Select '2012-12-16'
Union All
Select '2013-01-13'
Union All
Select '2013-01-27'
Select *,
Dense_Rank() Over (Order By Year(SampleDate),Quarters) As Tracker
From Blah
So you want a simple column to represent your actual quarter?
2012-Q1, 2011-Q1, 2010-Q1 that you would like to use SQL Partitions on? Or you want 2 columns? One to be partitioned on, and another one to actually indicate the year?
Thinking about it, do you need a counter? Couldn't you just set up the other column to be the year?
so you would have 2 columns. One indicating the quarter, and the other the year
quarter year
1 2011
1 2012
1 2010
I have the following table
RecordID Group Date Value
----------------------------------------
1 Test 1 1/01/2012 10
2 Test 1 1/01/2012 10
3 Test 1 1/01/2012 20
4 Test 2 1/01/2012 20
5 Test 1 2/01/2012 10
6 Test 2 2/01/2012 30
7 Test 1 2/01/2012 20
8 Test 1 2/01/2012 20
9 Test 2 2/01/2012 20
10 Test 1 3/01/2012 10
11 Test 2 3/01/2012 10
12 Test 2 3/01/2012 20
13 Test 3 3/01/2012 10
14 Test 1 4/01/2012 10
I need to get all RecordIds, where for the same date and same group it has the lowest value and disregard all records for the same date and group that have greater value. So my query needs to group by "date" and "group" and find records with lowest value, that is result should be:
RecordIds: 1, 2, 4, 5, 9, 10, 11, 13, 14
You can use rank in a sub query.
select T.RecordID,
T.[Group],
T.Date,
T.Value
from
(
select RecordID,
[Group],
Date,
Value,
rank() over(partition by [Group], Date order by Value) as rn
from YourTable
) as T
where T.rn = 1
order by T.RecordID
SQL Fiddle