EDIT: the server I'm working on is 2008 R2 but my client is 2012...
I'm trying to create a conditionnal sum based on the month I'm in backing up to one year ago.
Here is the data I have:
Month Location Quantity1 Quantity2
200501 2072 46 42
200502 2072 53 51
200503 2072 141 132
200504 2072 134 129
200505 2072 75 72
200506 2072 75 74
200507 2072 77 72
200508 2072 56 52
200509 2072 58 54
200510 2072 59 52
200511 2072 71 69
200512 2072 48 46
200601 2072 62 55
200602 2072 209 197
200603 2072 143 138
200604 2072 78 67
200605 2072 95 86
200606 2072 78 73
200607 2072 80 73
200608 2072 68 62
200609 2072 54 46
200610 2072 52 49
200611 2072 50 50
200612 2072 28 27
so, what I would like as an output is something like this:
for the first month(200501) only it can be in the total as there were no records prior to it, up to 200512 it would be between the starting month (200501) and the month in question. Once it goes to 200601, it has to be a sum between 200502 and 200601.
I did the mannual calculations to help the validation process, so here they are:
Month Location SumQty1 SumQty2
200501 2072 46 42
200502 2072 99 93
200503 2072 240 225
200504 2072 374 354
200505 2072 449 426
200506 2072 524 500
200507 2072 601 572
200508 2072 657 624
200509 2072 715 678
200510 2072 774 730
200511 2072 845 799
200512 2072 893 845
200601 2072 909 858
200602 2072 1065 1004
200603 2072 1067 1010
200604 2072 1011 948
200605 2072 1031 962
200606 2072 1034 961
200607 2072 1037 962
200608 2072 1049 972
200609 2072 1045 964
200610 2072 1038 961
200611 2072 1017 942
200612 2072 997 923
Thank you for your time!
You can join the table to itself to get all dates that need to be added:
SELECT t1.Month ,
t1.Location ,
SUM(t2.Quantity1) AS SumQty1 ,
SUM(t2.Quantity2) AS SumQty2
FROM dbname.schemaname.tablename t1
INNER JOIN dbname.schemaname.tablename t2 ON t2.month >= t1.month - 99
AND t2.month <= t1.month
GROUP BY t1.month ,
t1.location
Try windowing functions (http://msdn.microsoft.com/en-GB/library/ms189461.aspx):
SELECT Month, Location,
SUM(Quantity1)
OVER (PARTITION BY Location ORDER BY Month ROWS 11 preceding) as SumQty1,
SUM(Quantity2)
OVER (PARTITION BY Location ORDER BY Month ROWS 11 preceding) as SumQty2
FROM
(SELECT 200501 as Month, 2072 as Location, 46 as Quantity1, 42 as Quantity2
UNION SELECT 200502, 2072, 53, 51
UNION SELECT 200503, 2072, 141, 132
...) as t;
Although note that this will only work if there are no missing months.
Related
I have a dataset of price data and would like to get the calculation of the ongoing ATR (Average True Range) for all rows > 21. Row 21 is the AVG([TR]) from Rows 2-21 and is equal to 353.7.
The calculation that needs to be continuous for the rest of that [ATR_20] column will need to be:
ATR_20 (after row 21) = (([Previous ATR_20]*19)+[TR])/20
My dataset:
Date Open High Low Close TotalVolume Prev_Close TR_A TR_B TR_C TR ATR
2017-02-01 5961 5961 5425 5498 22689 NULL 536 NULL NULL NULL NULL
2017-02-02 5697 5868 5615 5734 22210 5498 253 370 117 370 NULL
2017-02-03 5742 5811 5560 5725 15852 5734 251 77 174 251 NULL
2017-02-06 5675 5679 5545 5554 9777 5725 134 46 180 180 NULL
2017-02-07 5597 5613 5426 5481 12692 5554 187 59 128 187 NULL
2017-02-08 5459 5630 5450 5625 9134 5481 180 149 31 180 NULL
2017-02-09 5615 5738 5532 5668 10630 5625 206 113 93 206 NULL
2017-02-10 5651 5661 5488 5602 9709 5668 173 7 180 180 NULL
2017-02-13 5700 6195 5639 6161 26031 5602 556 593 37 593 NULL
2017-02-14 6197 6594 6073 6571 35969 6161 521 433 88 521 NULL
2017-02-15 6510 6650 6275 6492 22046 6571 375 79 296 375 NULL
2017-02-16 6505 6680 6325 6419 12515 6492 355 188 167 355 NULL
2017-02-17 6434 6670 6429 6658 14947 6419 241 251 10 251 NULL
2017-02-21 6800 6957 6603 6654 23838 6658 354 299 55 354 NULL
2017-02-22 6704 6738 6145 6222 25004 6654 593 84 509 593 NULL
2017-02-23 6398 6437 5901 6343 46677 6222 536 215 321 536 NULL
2017-02-24 5280 5589 5260 5404 51757 6343 329 754 1083 1083 NULL
2017-02-27 5437 5461 5260 5300 19831 5404 201 57 144 201 NULL
2017-02-28 5258 5410 5167 5195 15900 5300 243 110 133 243 NULL
2017-03-01 5251 5299 5052 5215 16958 5195 247 104 143 247 NULL
2017-03-02 5160 5231 5063 5130 17805 5215 168 16 152 168 353.7
2017-03-03 5141 5363 5088 5320 14516 5130 275 233 42 275 NULL
I got to this point by the following
WITH cte_ACIA ([RowNumber], [Date], [Open], [High], [Low], [Close],
[Prev_Close], [TotalVolume], [TR_A], [TR_B], [TR_C])
AS
(SELECT
ROW_NUMBER() OVER (ORDER BY [Date] ASC) RowNumber,
[Date],
[Open],
[High],
[Low],
[Close],
LAG([Close]) OVER(ORDER BY [Date]) AS Prev_Close,
[TotalVolume],
ROUND([High]-[Low], 5) AS TR_A,
ABS(ROUND([High]-LAG([Close]) OVER(ORDER BY [Date]), 5)) AS TR_B,
ABS(ROUND([Low]-LAG([Close]) OVER(ORDER BY [Date]), 5)) AS TR_C,
FROM NASDAQ.ACIA_TEMP)
SELECT [RowNumber], [Date], [Open], [High], [Low], [Close], [Prev_Close],
[TotalVolume], [TR_A], [TR_B], [TR_C], [TR],
CASE
WHEN RowNumber = 21 THEN AVG([TR]) OVER (ORDER BY [Date] ASC ROWS 19 PRECEDING)
END AS ATR_20
FROM
(
SELECT [RowNumber],[Date],[Open],[High],[Low],[Close],
IIF(RowNumber = 1, NULL, Prev_Close) Prev_Close,
[TotalVolume],
[TR_A],
IIF(RowNumber > 1, [TR_B], NULL) TR_B,
IIF(RowNumber > 1, [TR_C], NULL) TR_C,
CASE
WHEN TR_A > TR_B AND TR_A > TR_C THEN TR_A
WHEN TR_B > TR_A AND TR_B > TR_C THEN TR_B
ELSE TR_C
END AS TR
FROM cte_ACIA) sub
Please let me know if you have questions or I need to clarify anything.
I suppose you are just looking for a hint. Otherwise you would have posted your table definition. We can't construct a query for you since we don't have the basic pieces. However, here's the hint! Use an aggregating window function with the OVER clause specifying ROWS PRECEDING.
See SELECT - OVER Clause
we use MS SQL 2008 r2 and
we have this 2 table its for time attendance
select CHECKINOUT.USERID ,USERINFO.USERID,CHECKINOUT.SENSORID,
userinfo.BADGENUMBER,CHECKINOUT.CHECKTIME
from CHECKINOUT , userinfo
where CHECKINOUT.USERID=userinfo.userid
and userinfo.BADGENUMBER=63 and CHECKTIME
between '2017-03-26' and '2017-04-26'
USERID USERID SENSORID BADGENUMBER CHECKTIME
181 181 100 63 2017-04-01 11:02:19.000
181 181 100 63 2017-04-02 10:12:52.000
181 181 100 63 2017-04-03 10:32:43.000
181 181 1 63 2017-04-04 19:21:26.000
181 181 100 63 2017-04-05 19:54:30.000
181 181 100 63 2017-04-06 10:00:52.000
181 181 100 63 2017-04-07 09:54:49.000
181 181 100 63 2017-04-08 10:40:20.000
181 181 100 63 2017-04-11 10:21:47.000
181 181 100 63 2017-04-12 13:32:00.000
181 181 100 63 2017-04-12 19:17:13.000
181 181 100 63 2017-04-13 11:07:02.000
181 181 100 63 2017-04-13 18:34:37.000
181 181 100 63 2017-04-15 18:49:02.000
181 181 100 63 2017-04-15 18:49:10.000
181 181 1 63 2017-04-16 10:17:58.000
181 181 100 63 2017-04-18 10:31:47.000
181 181 100 63 2017-04-18 18:39:54.000
181 181 100 63 2017-04-19 10:54:00.000
181 181 100 63 2017-04-20 10:45:03.000
181 181 100 63 2017-04-22 10:25:09.000
181 181 100 63 2017-04-22 18:45:21.000
181 181 100 63 2017-04-22 18:45:26.000
181 181 100 63 2017-04-23 10:18:01.000
181 181 100 63 2017-04-24 10:20:59.000
181 181 100 63 2017-04-24 18:41:07.000
181 181 100 63 2017-04-25 11:13:48.000
and we need to have from this 2 table check date and chick in and check out and sensor id
(Main(CHECKINOUT.CHECKTIME) as Checkin , Max(CHECKINOUT.CHECKTIME)as Check out )
first check in and last check out and the time between Min and Max its from 6:00 AM and 5:00 AM next day its 23 hours and the subtract between checkin and checkout as hours
for example
USERID USERID SENSORID BADGENUMBER CHECKTIME
181 181 100 63 2017-04-01 10:02:19.000
181 181 100 63 2017-04-01 18:12:52.000
181 181 100 63 2017-04-02 10:32:43.000
181 181 100 63 2017-04-03 01:21:26.000
181 181 100 63 2017-04-04 10:54:30.000
181 181 100 63 2017-04-04 18:00:52.000
181 181 100 63 2017-04-05 09:54:49.000
181 181 100 63 2017-04-05 23:40:20.000
181 181 100 63 2017-04-06 10:21:47.000
181 181 100 63 2017-04-07 03:32:00.000
to be like that
BADGENUMBER SENSORID CHECKDate Checkin Checkout Hours
63 100 2017-04-01 10:02:19 18:12:52 8:10
63 100 2017-04-02 10:32:43 01:21:26 14:49
63 100 2017-04-04 10:54:30 18:00:52 07:06
63 100 2017-04-05 09:54:49 23:40:20 13:46
63 100 2017-04-06 10:21:47 03:32:00 17:11
This might get you the required result
select u.BADGENUMBER, attendance.SENSORID, attendance.CHECKDate, attendance.CheckIn ,attendance.CheckOut
,cast(DATEDIFF(n, attendance.CheckIn, attendance.checkout) / 60 as varchar) + ':' + cast(DATEDIFF(n, attendance.CheckIn, attendance.checkout) % 60 as varchar) as Minutes
from (
select temp.USERID, temp.SENSORID, temp.CHECKDate ,temp.CheckIn
,case when temp.COut = temp.CheckIn then null when temp.CheckIn is null then null else temp.COut end as CheckOut
from(
select c.USERID, c.SENSORID, convert(date, CHECKTIME) CHECKDate
,(select min(CHECKTIME) from CHECKINOUT cinout where cinout.USERID = c.USERID and cinout.SENSORID = c.SENSORID and cinout.CheckTime >= dateadd(hour, 6, convert(datetime, convert(date, c.CheckTime)))) CheckIn
,(select max(CHECKTIME) from CHECKINOUT cinout where cinout.USERID = c.USERID and cinout.SENSORID = c.SENSORID and cinout.CheckTime <= dateadd(hour, 29, convert(datetime, convert(date, c.CheckTime)))) COut
from CHECKINOUT c
group by c.USERID, c.SENSORID, convert(date, CHECKTIME)
)temp
) attendance
inner join userinfo u on u.USERID = attendance.USERID
where u.BADGENUMBER = 63 and CHECKDate
between '2017-03-26' and '2017-04-26'
I have been given a database(MS Dynamic Navision) which has a table with Item translations. Some entries have the item description in russian example ’ąćŖ Æ®«Ø ¬Ø¤ ļ and how do I translate or convert it to normal cyrillic text?
The binary value for the example text is 0x92E0E3A1AAA020AFAEABA8A0ACA8A4ADA0EF
I know that the column is cp1257(character_set) and collation is Latvian_CI_AS.
Here are some more example data if it helps.
‡ Ŗ«ÆŖØ 0x87A0AAABA5AFAAA8
®ā ¦ ļ Ŗ®į®«ģ 0x8CAEADE2A0A6ADA0EF20AAAEADE1AEABEC
‘āļ¦Ŗ 0x91E2EFA6AAA0
©Ŗ Ŗ®«į 0x83A0A9AAA020AAAEABA5E1A0
¸ą®Ŗ« ¤Ŗ 0x8FE0AEAAABA0A4AAA0
From SQL.RU CP866 to CP1251
create function cp866_to_1251(#instr varchar(8000))
returns varchar(8000)
as begin
declare #res varchar(8000)
set #res = ''
if not (#instr is null) begin
declare #i as int
declare #n as int
declare #char_code_866 as int
declare #char_code_1251 as int
set #n = datalength(#instr)
set #i = 1
while #i<=#n begin
set #char_code_866 = ascii(substring(#instr, #i, 1))
select #char_code_1251 =
case #char_code_866
when 15 then 164
when 20 then 182
when 21 then 167
when 128 then 192
when 129 then 193
when 130 then 194
when 131 then 195
when 132 then 196
when 133 then 197
when 134 then 198
when 135 then 199
when 136 then 200
when 137 then 201
when 138 then 202
when 139 then 203
when 140 then 204
when 141 then 205
when 142 then 206
when 143 then 207
when 144 then 208
when 145 then 209
when 146 then 210
when 147 then 211
when 148 then 212
when 149 then 213
when 150 then 214
when 151 then 215
when 152 then 216
when 153 then 217
when 154 then 218
when 155 then 219
when 156 then 220
when 157 then 221
when 158 then 222
when 159 then 223
when 160 then 224
when 161 then 225
when 162 then 226
when 163 then 227
when 164 then 228
when 165 then 229
when 166 then 230
when 167 then 231
when 168 then 232
when 169 then 233
when 170 then 234
when 171 then 235
when 172 then 236
when 173 then 237
when 174 then 238
when 175 then 239
when 176 then 45
when 177 then 45
when 178 then 45
when 179 then 166
when 180 then 43
when 181 then 166
when 182 then 166
when 183 then 172
when 184 then 172
when 185 then 166
when 186 then 166
when 187 then 172
when 188 then 45
when 189 then 45
when 190 then 45
when 191 then 172
when 192 then 76
when 193 then 43
when 194 then 84
when 195 then 43
when 196 then 45
when 197 then 43
when 198 then 166
when 199 then 166
when 200 then 76
when 201 then 227
when 202 then 166
when 203 then 84
when 204 then 166
when 205 then 61
when 206 then 43
when 207 then 166
when 208 then 166
when 209 then 84
when 210 then 84
when 211 then 76
when 212 then 76
when 213 then 45
when 214 then 227
when 215 then 43
when 216 then 43
when 217 then 45
when 218 then 45
when 219 then 45
when 220 then 45
when 221 then 166
when 222 then 166
when 223 then 45
when 224 then 240
when 225 then 241
when 226 then 242
when 227 then 243
when 228 then 244
when 229 then 245
when 230 then 246
when 231 then 247
when 232 then 248
when 233 then 249
when 234 then 250
when 235 then 251
when 236 then 252
when 237 then 253
when 238 then 254
when 239 then 255
when 240 then 168
when 241 then 184
when 242 then 170
when 243 then 186
when 244 then 175
when 245 then 191
when 246 then 161
when 247 then 162
when 248 then 176
when 249 then 149
when 250 then 183
when 251 then 118
when 252 then 185
when 253 then 164
when 254 then 166
when 255 then 160
else
#char_code_866
end
set #res = #res + char(#char_code_1251)
set #i = #i + 1
end
end
return #res
end
InsertID OrderID Line OrderNo ProductNo ModelID Name PlanQuantity PlanStartDate PlanStartTime
18 215051544 Lien1 249 7626488955 77279 DFS05510S 68 2016-05-10 16:53:16
18 215050561 Lien1 246 7618483945 77285 DFS28023X 50 2016-05-10 16:56:47
18 215050459 Lien1 247 7618483945 77285 DFS28023X 60 2016-05-10 17:15:57
18 215048653 Lien1 248 7622583955 77282 DD Sample 53 2016-05-10 17:38:57
18 215051588 Lien1 249 7626488955 77279 DFS05510S 10 2016-05-10 18:09:16
18 215051587 Lien1 250 7626488955 77279 DFS05510S 15 2016-05-10 18:13:07
18 215051138 Lien1 251 7626488955 77279 DFS05510S 20 2016-05-10 18:18:53
18 213798175 Lien1 252 7635383842 96365 LAM8603 341 2016-05-10 18:26:33
Sample Table is here , I am want replacing to the same model and product rows. Only consecutive rows and order no 249-250-251
Need to Example Table Output ;
InsertID OrderID Line OrderNo ProductNo ModelID Name PlanQuantity PlanStartDate PlanStartTime Orders Quantitys
18 215051544 Lien1 249 7626488955 77279 DFS05510S 68 2016-05-10 16:53:13
18 215050561 Lien1 246 7618483945 77285 DFS28023X 110 2016-05-10 16:56:47 215050561,215050459 50,60
18 215048653 Lien1 248 7622583955 77282 DD Sample 53 2016-05-10 17:38:57
18 215051588 Lien1 249 7626488955 77279 DFS05510S 45 2016-05-10 18:09:16 215051588,215051587,215051138 10,15,20
18 213798175 Lien1 252 7635383842 96365 LAM8603 341 2016-05-10 18:26:33
How to easy for me ? Linq or SQL server View , sql procedure ?
I want to Vb.net applicaton views to output table ,
Aynone Is Idea for this situation?
I've sifted through the various sql-server tagged threads using AVERAGE and Cumulative as search terms. Various desperate answers, but I can't cobble them together for my needs. The use case is to find the initial average value (cumulative value/cumulative days on) for a time period when cumulative days on is greater than 60 and less than 90.
Below is a table where ID identifies the object, VALUE is the amount reported on a monthly basis and DAYSON is the number of days in that month where the object ran to produce the value. YEARMONTH is date value on which on can sort.
ID VALUE DASYON YEARMONTH
1 166 27 201502
1 1 2 201505
1 569 19 201507
1 312 19 201508
2 364 27 201502
2 328 31 201503
2 242 29 201504
2 273 31 201505
2 174 30 201506
2 188 25 201507
2 203 25 201508
3 474 28 201502
3 521 31 201503
3 465 30 201504
3 473 31 201505
3 434 30 201506
3 404 31 201507
I would like to create a summary table that averages the cumulative value divided by the cumulative days uniquely for each ID where cumulative days is greater than 60 and less than 90. Below is a table that with the cumulative values. (I generated this in Excel)
ID VALUE cumValue DASYON cumDaysOn YEARMONTH
1 166 166 27 27 201502
1 1 167 2 29 201505
1 569 736 19 48 201507
1 312 1048 19 67 201508
2 364 364 27 27 201502
2 328 692 31 58 201503
2 242 934 29 87 201504
2 273 1207 31 118 201505
2 174 1381 30 148 201506
2 188 1569 25 173 201507
2 203 1772 25 198 201508
3 474 474 28 28 201502
3 521 505 31 59 201503
3 465 535 30 89 201504
3 473 566 31 120 201505
3 434 596 30 150 201506
3 404 627 31 181 201507
I try this based on other threads:
SELECT
ID,
Value,
SUM(Value) OVER (ORDER BY ID, YearMonth) [cumValue],
DaysOn,
SUM (DaysOn) OVER (Order by ID, YearMonth) as cumDaysOn,
YearMonth
FROM table
WHERE DAYSON > 0 and Liquid > 0 and YearMonth > 201501
GROUP BY ID, YearMonth, Value, DaysOn
ORDER BY ID, yearmonth
I can't get it to iterate over the ID; it just keeps summing down the column. If I could create a table or view like the one above, then I could always use a select statement and divide cumvalue by cumdayson.
Below is a table to show where I would get the initial average value (InititalAverageValue) based on the criteria:
ID VALUE cumValue DASYON cumDaysOn YEARMONTH InitalAvgValue
1 166 166 27 27 201502
1 1 167 2 29 201505
1 569 736 19 48 201507
1 312 1048 19 67 201508 55
2 364 364 27 27 201502
2 328 692 31 58 201503
2 242 934 29 87 201504 32
2 273 1207 31 118 201505
2 174 1381 30 148 201506
2 188 1569 25 173 201507
2 203 1772 25 198 201508
3 474 474 28 28 201502
3 521 505 31 59 201503
3 465 535 30 89 201504 18
3 473 566 31 120 201505
3 434 596 30 150 201506
3 404 627 31 181 201507
Ultimately what I desire is table as such:
ID InitalAvgValue
1 55
2 32
3 18
Thanks in advance for any help.
The crux is that you need a running total. There are several approaches to calculating running totals, but they have various tradeoffs between simplicity and performance. The "best" approach depends on the expected size of your data set and whether you are using SQL Server 2012 or an earlier version. The following article describes some different options along with the pros and cons:
http://sqlperformance.com/2012/07/t-sql-queries/running-totals
Here's a quick example using correlated subqueries, which may be reasonable for small data sets, but likely would not scale well to larger data:
SELECT
ID,
ROUND(AVG(CAST(CumulativeValue AS FLOAT) / CAST(CumulativeDaysOn AS FLOAT)), 1) AS Average
FROM
(
SELECT
ID,
Value,
DaysOn,
(SELECT SUM(Value) FROM ExampleTable t2 WHERE t1.ID = t2.ID and t2.YearMonth <= t1.YearMonth) AS CumulativeValue,
(SELECT SUM(DaysOn) FROM ExampleTable t2 WHERE t1.ID = t2.ID and t2.YearMonth <= t1.YearMonth) AS CumulativeDaysOn
FROM
ExampleTable t1
) AS ExampleWithTotals
WHERE
CumulativeDaysOn > 60 AND CumulativeDaysOn < 90
GROUP BY
ID
ORDER BY
ID
;
Output:
ID Average
1 15.6
2 10.7
3 16.4