I need to modify a table based on multiple fields in that same table, and i can't seem to get it right and it is becomming a real pain.
My table looks like this:
Id person code product item delivery
41 254252 1368 prodname 561352401 23
41 254252 1368 prodname 4421252401 23
42 254252 1368 prodname 2501552403 23
42 254252 1368 prodname 5281352400 23
45 254251 1368 prodname 561352401 56
46 254251 1368 prodname 2501552403 56
49 254250 1368 prodname 561352401 69
50 254250 1368 prodname 2501552403 69
1357 253288 1368 prodname 4421252401 2
1358 253288 1368 prodname 5281352400 2
1359 253288 1368 prodname 9990070900 2
1377 253263 1220 prodname 2331252400 11
1378 253263 1220 prodname 2461252403 11
1379 253263 1220 prodname 9990070900 11
I need to update the delivery column based on: person, code and product. When the value in one of these column changes it should set it's counter to 0.
I need the output to look like this:
Id person code product item delivery
41 254252 1368 prodname 561352401 23
41 254252 1368 prodname 4421252401 24
42 254252 1368 prodname 2501552403 25
42 254252 1368 prodname 5281352400 26
45 254251 1368 prodname 561352401 56
46 254251 1368 prodname 2501552403 57
49 254250 1368 prodname 561352401 69
50 254250 1368 prodname 2501552403 70
1357 253288 1368 prodname 4421252401 2
1358 253288 1368 prodname 5281352400 3
1359 253288 1368 prodname 9990070900 4
1377 253263 1220 prodname 2331252400 11
1378 253263 1220 prodname 2461252403 12
1379 253263 1220 prodname 9990070900 13
So far i have this:
DECLARE #Id INT
DECLARE #person INT
DECLARE #code VARCHAR(15)
DECLARE #product VARCHAR(10)
DECLARE #Itemtype VARCHAR(10)
DECLARE #Item VARCHAR(50)
DECLARE #Delivery INT
DECLARE sel_cursor CURSOR FOR
SELECT Id, person, code, product, delivery FROM [dbo].[orders]
WHERE Itemtype = 'ART'
ORDER BY person, product,Itemtype, Item, delivery desc
DECLARE #Counter INT
OPEN sel_cursor
set #Counter = 0
FETCH NEXT FROM sel_cursor
INTO #Id, #person, #code, #product, #Delivery
WHILE ##FETCH_STATUS = 0
BEGIN
--WHILE (SELECT COUNT(*) FROM orders WHERE person=#person AND code=#code and product=#product) > 0
BEGIN
UPDATE Orders
SET delivery = (delivery + #Counter) WHERE person=#person AND code=#code AND product=#product
set #Counter = #Counter + 1
END
FETCH NEXT FROM sel_cursor
INTO #Id, #person, #code, #product, #Delivery
set #Counter = 0
END
CLOSE sel_cursor
DEALLOCATE sel_cursor
END
DECLARE #t TABLE (
Id INT,
person INT,
code VARCHAR(10),
product VARCHAR(20),
item VARCHAR(20),
delivery INT
)
INSERT INTO #t
VALUES
(41 , 254252, 1368, 'prodname', '561352401 ', 23),
(41 , 254252, 1368, 'prodname', '4421252401', 23),
(42 , 254252, 1368, 'prodname', '2501552403', 23),
(42 , 254252, 1368, 'prodname', '5281352400', 23),
(45 , 254251, 1368, 'prodname', '561352401 ', 56),
(46 , 254251, 1368, 'prodname', '2501552403', 56),
(49 , 254250, 1368, 'prodname', '561352401 ', 69),
(50 , 254250, 1368, 'prodname', '2501552403', 69),
(1357, 253288, 1368, 'prodname', '4421252401', 2 ),
(1358, 253288, 1368, 'prodname', '5281352400', 2 ),
(1359, 253288, 1368, 'prodname', '9990070900', 2 ),
(1377, 253263, 1220, 'prodname', '2331252400', 11),
(1378, 253263, 1220, 'prodname', '2461252403', 11),
(1379, 253263, 1220, 'prodname', '9990070900', 11)
;WITH cte AS
(
SELECT *, RowNum = ROW_NUMBER() OVER (
PARTITION BY Person, Code, product
ORDER BY 1/0) - 1
FROM #t
)
UPDATE cte
SET delivery += RowNum
SELECT * FROM #t
Output -
Id person code product item delivery
----------- ----------- ---------- ---------- ------------- -----------
41 254252 1368 prodname 561352401 23
41 254252 1368 prodname 4421252401 24
42 254252 1368 prodname 2501552403 25
42 254252 1368 prodname 5281352400 26
45 254251 1368 prodname 561352401 56
46 254251 1368 prodname 2501552403 57
49 254250 1368 prodname 561352401 69
50 254250 1368 prodname 2501552403 70
1357 253288 1368 prodname 4421252401 2
1358 253288 1368 prodname 5281352400 3
1359 253288 1368 prodname 9990070900 4
1377 253263 1220 prodname 2331252400 11
1378 253263 1220 prodname 2461252403 12
1379 253263 1220 prodname 9990070900 13
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
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?
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.
I have a table that lists visits to a clinic. I'd like to get a "histogram" of sorts showing how frequently patients visit the clinic along with totals. Here's some sample code (tested under MS SQL Server 2005) to show what I'm talking about:
CREATE TABLE #test (
visit_id int IDENTITY(1,1),
patient_id int
);
DECLARE #num_patients int;
SELECT #num_patients = 1000 + ABS(CHECKSUM(NEWID())) % 250;
INSERT INTO #test (patient_id)
SELECT TOP 15 PERCENT ABS(CHECKSUM(NEWID())) % #num_patients
FROM sysobjects a, sysobjects b;
-- SELECT COUNT(*) AS total_visits FROM #test;
-- SELECT COUNT(DISTINCT patient_id) AS distinct_patients FROM #test;
SELECT CASE GROUPING(num_pat_visits) WHEN 1 THEN 'Total'
ELSE CAST(num_pat_visits AS varchar(5)) END AS num_pat_visits,
COUNT(*) AS num_patients, num_pat_visits * COUNT(*) AS tot_pat_visit
FROM
(SELECT patient_id, COUNT(*) AS num_pat_visits FROM #test GROUP BY patient_id) a
GROUP BY num_pat_visits WITH ROLLUP
ORDER BY CAST(num_pat_visits AS int) DESC;
This gets me almost to where I want:
num_pat_visits num_patients tot_pat_visit
-------------- ------------ -------------
60 1 60
54 2 108
52 2 104
51 4 204
50 3 150
49 3 147
48 7 336
47 7 329
46 15 690
45 15 675
44 29 1276
43 36 1548
42 45 1890
41 45 1845
40 59 2360
39 71 2769
38 51 1938
37 72 2664
36 77 2772
35 74 2590
34 72 2448
33 82 2706
32 90 2880
31 74 2294
30 69 2070
29 47 1363
28 30 840
27 27 729
26 26 676
25 21 525
24 13 312
23 4 92
22 5 110
21 4 84
20 2 40
18 2 36
Total 1186 NULL
However, I can't seem to get SQL Server to display the total number of visits where it says NULL on the total row.
Any ideas?
I think you can just do:
sum(num_pat_visits) as tot_pat_visit
SELECT CASE GROUPING(num_pat_visits) WHEN 1 THEN 'Total'
ELSE CAST(num_pat_visits AS varchar(5)) END AS num_pat_visits,
COUNT(*) AS num_patients,
--num_pat_visits * COUNT(*) AS tot_pat_visit
sum(num_pat_visits) as tot_pat_visit
FROM
(SELECT patient_id, COUNT(*) AS num_pat_visits FROM #test GROUP BY patient_id) a
GROUP BY num_pat_visits WITH ROLLUP
ORDER BY CAST(num_pat_visits AS int) DESC;
This question already has an answer here:
Closed 12 years ago.
Possible Duplicate:
How to join two tables
table 1
Date StartingAum
07/01/2010 120
08/01/2010 220
09/01/2010 320
table 2
Date DepContr withdra
01/01/2010 60 15
02/01/2010 70 25
03/01/2010 80 15
04/01/2010 30 89
05/01/2010 40 15
06/01/2010 25 85
07/01/2010 16 17
08/01/2010 19 21
09/01/2010 68 79
the output should be
Date StartingAum DepContr withdra
01/01/2010 0 60 15
02/01/2010 0 70 25
03/01/2010 0 80 15
04/01/2010 0 30 89
05/01/2010 0 40 15
06/01/2010 0 25 85
07/01/2010 120 16 17
08/01/2010 220 19 21
09/01/2010 320 68 79
i need the output exactly similar to that
DECLARE #Table1 table ([date] datetime, StartingAum int)
DECLARE #Table2 table ([date] datetime, DepContr int, withdra int)
INSERT #Table1 VALUES ('07/01/2010', 120)
INSERT #Table1 VALUES ('08/01/2010', 220)
INSERT #Table1 VALUES ('09/01/2010', 320)
INSERT #Table2 VALUES ('01/01/2010', 60 , 15)
INSERT #Table2 VALUES ('02/01/2010', 70 , 25)
INSERT #Table2 VALUES ('03/01/2010', 80 , 15)
INSERT #Table2 VALUES ('04/01/2010', 30 , 89)
INSERT #Table2 VALUES ('05/01/2010', 40 , 15)
INSERT #Table2 VALUES ('06/01/2010', 25 , 85)
INSERT #Table2 VALUES ('07/01/2010', 16 , 17)
INSERT #Table2 VALUES ('08/01/2010', 19 , 21)
INSERT #Table2 VALUES ('09/01/2010', 68 , 79)
SELECT
t2.[Date]
,ISNULL(t1.StartingAum, 0) AS StartingAum
,t2.DepContr
,t2.withdra
FROM #Table2 t2
LEFT JOIN #Table1 t1 ON t2.[Date] = t1.[Date]
ORDER BY t2.[Date]
OUTPUT:
Date StartingAum DepContr withdra
----------------------- ----------- ----------- -----------
2010-01-01 00:00:00.000 0 60 15
2010-02-01 00:00:00.000 0 70 25
2010-03-01 00:00:00.000 0 80 15
2010-04-01 00:00:00.000 0 30 89
2010-05-01 00:00:00.000 0 40 15
2010-06-01 00:00:00.000 0 25 85
2010-07-01 00:00:00.000 120 16 17
2010-08-01 00:00:00.000 220 19 21
2010-09-01 00:00:00.000 320 68 79
I think you should have a look at this page: http://www.w3schools.com/sql/sql_union.asp
That might be helpful?