Crosstab interpolate data so graph 'connects the dots'
I have trouble with my crosstab or graph not interpolating the data correctly. I think this can be solved, but I'm not sure. Let me explain what I did.
I have a datacube with the rows grouping data by weeknumber and the cols grouping data per recordtype. I added to flagbits to the dataset so I can see if a record is new or old. In the datacube I added a measure to sum these bits per row/col group. Thus effectively counting new and old records per week per coltype. I also added a sum of records per coltype.
In the crosstab I added two runningsums for the new and old records sums. In the crosstab I added a datacell to calculate the actual records per row/colgroup. Thus actual records = totalcoltype - runningsum(old) + runningsum(new)
So lets say there are 20 records in this set for a coltype.
In week 1: 3 old records, 2 new records. Then the running sum becomes 3 and -2. Actual = 20 - 3 + 2 = 19 (correct)
In week 2: no data. The runningsums are not visible. Actual = 20 - null + null = 20 (wrong)
In week 3: no data. The runningsums are not visible. Actual = 20 - null + null = 20 (wrong)
In week 4: 2 old records, 1 new recored. The runningsums becomes 5 and 3. Actual = 20 - 5 + 3 = 18 (correct)
In week 5: no data. The runningsums are not visible. Actual = 20 - null + null = 20 (wrong)
In week 6: 6 old records, 2 new records. The runningsums becomes 11 and 5. Actual = 20 - 11 + 5 = 14 (correct)
In week 7: no data. The runningsums are not visible. Actual = 20 - null + null = 20 (wrong)
So the graph will display:
19
20
20
18
20
14
20
If I add a condition to the actual calculation, it becomes:
19
null
null
18
null
14
null
The graph doesn't ignore the null values, but thinks they are 0. The graph is wrong.
Is there a way to let the graph realy ignore the null values?
Another solution is that the runningsums display the last know value or just add 0 if there is no data. Any idea how to do this?
Obviously, a correct graph would read:
19
19
19
18
18
14
14
Related
I have table which shows time difference between different types of ID's for when an alert is given. The time since prev will say when the next alert is on the device ID.
my table looks like this:
Time Device ID Type TimeSincePrev(seconds) index
22.1.21 04:02:04 12 None 0 1
22.1.21 04:24:07 13 low 1320 2
22.1.21 04:26:04 14 medium 120 3
......
...
......
...
...
However When I filter by deviceID, the indexes will not reset to 1,2,3...., instead, it will go to a random number, causing the timesinceprev alert to be wrong. How do I correct so that index is correct, hopefully correcting the TimeSincePrev column. Also if there is a way to get TimeSincePrev to show seconds via the the seconds and not just via the minute like it is now
This is what the query for the index column looks like:
index= COUNTROWS(FILTER(VALUES('Table'[Time]),
'Table'[Time]<EARLIER('Table'[Time])
))+1
Here is how TimeSincePrev:
TimeSincePrev= IF(DATEDIFF(LOOKUPVALUE('Table'[Time],'Table'[index],
'Table'[index]-1),MINUTE)>720,BLANK(),DATEDIFF(LOOKUPVALUE('Table'[Time],
'Table'[index],'Table'[index]-1),'Table'[Time],MINUTE))*60
How do I get it so when I filter by device ID the indexes don't mess up like this:
Time Device ID Type TimeSincePrev(seconds) index
22.1.21 04:02:04 12 None 0 6
22.1.21 04:24:07 12 low 1320 3
22.1.21 04:26:04 12 medium 120 1
22.1.21 04:02:04 12 None 0 2
22.1.21 04:24:07 12 low 1320 4
22.1.21 04:26:04 12 medium 120 5
......
...
......
...
...
Are you using a column for this? If so, you need to create a measure that handles the indexing instead.
Columns are re-calculated only at refresh time (when you refresh the dataset), NOT at query time (when you click on slicers). The column cannot respond to your selected slicer value and calculate on the fly.
This is a very complicated situation for me and I was wondering if someone can help me with it:
Here is my table:
Record_no Type Solde SQLCalculatedPmu DesiredValues
------------------------------------------------------------------------
2570088 Insertion 60 133 133
2636476 Insertion 67 119,104 119,104
2636477 Insertion 68 117,352 117,352
2958292 Insertion 74 107,837 107,837
3148350 Radiation 73 107,837 107,83 <---
3282189 Insertion 80 98,401 98,395
3646066 Insertion 160 49,201 49,198
3783510 Insertion 176 44,728 44,725
3783511 Insertion 177 44,475 44,472
4183663 Insertion 188 41,873 41,87
4183664 Insertion 189 41,651 41,648
4183665 Radiation 188 41,651 41,64 <---
4183666 Insertion 195 40,156 40,145
4183667 Insertion 275 28,474 28,466
4183668 Insertion 291 26,908 26,901
4183669 Insertion 292 26,816 26,809
4183670 Insertion 303 25,842 25,836
4183671 Insertion 304 25,757 25,751
In my table every value in the SQLCalculatedPmu column or desiredValue Column is calculated based on the preceding value.
As you can see, I have calculated the SQLcalculatedPMU column based on the round on 3 decimals. The case is that on each line radiation, the client want to start the next calculation based on 2 decimals instead of 3(represented in the desired values column). Next values will be recalculated. For example line 6 will change as the value in line 5 is now on 2 decimals. I could handle this if there where one single radiation but in my case I have a lot of Radiations and in this case they will change all based on the calculation of the two decimals.
In summary, Here are the steps:
1 - round the value of the preceding row of a raditaiton and put it in the radiation row.
2 - calculate all next insertion rows.
3 - when we reach another radiation we redo steps 1 and 2 and so on
I m using an oracle DB and I m the owner so I can make procedures, insert, update, select.
But I m not familiar with procedures or loops.
For information, this is the formula for SQLCalculatedPmu uses two additional culmns price and number and this is calculated every line cumulativelly for each investor:
(price * number)+(cumulative (price*number) of the preceeding lines)
I tried something like this :
update PMUTemp
set SQLCalculatedPmu =
case when Type = 'Insertion' then
(number*price)+lag(SQLCalculatedPmu ,1) over (partition by investor
order by Record_no)/
(number+lag(solde,1) over (partition by investor order by Record_no))
else
TRUNC(lag(SQLCalculatedPmu,1) over partition by invetor order by Record_no))
end;
but I gave me this error (I think it's because I m looking at the preceiding line that itself is modified during the SQL statement) :
ORA-30486 : window function are allowed only in the SELECT list of a query.
I was wondering if creating a procedure that will be called as many time as the number of radiations would do the job but I m really not good in procedures
Any help
Regards,
just to make my need simpler, all I want is to have the DesiredValues column starting from the SQLCalculatedPmu column. Steps are
1 - on a radiation the value become = trunc(preceding value,2)
2 - calculate all next insertion rows this way : (price * number)+(cumulative (price*number) of the preceeding lines). As the radiation value have changed then I need to recalculate next lines based on it
3 - when we reach another radiation we redo steps 1 and 2 and so on
Kindest regards
You should not need a procedure here -- a SQL update of the Radiation rows in the table would do this quicker and more reliably.
Something like ..
update my_table t1
set (column_1, column_2) =
(select round(column_1,2), round(column_2,2)
from my_table t2
where t2.type = 'Insertion' and
t2.record_no = (select max(t3.record_no)
from my_table t3
where t3.type = 'Insertion' and
t3.record_no < t1.record_no ))
where t1.type = 'Radiation'
I am new to oracle and I have a problem.
I have a column named file_id.
When I do an order by it sorts strings such as
1
1
10
100
11
11
110
114
12
300
31
4200
B14
B170
B18
edit:
I would like it to sort this way.
1
1
10
11
11
12
31
100
300
4200
B14
B18
B170
The answer below works perfectly. Only other problem I ran into now..I have records that are blank. How could I make the blank records order at the end?
1
1
10
11
11
12
31
100
300
4200
BLANK
BLANK
BLANK
BLANK
BLANK
B14
B18
B170
Thank you for your help.
select column
from table
order by
regexp_substr(column, '^\D*') nulls first,
to_number(regexp_substr(column, '\d+'))
fiddle
This is an old question, but it was the first hit on google so I thought I'd share an alternative solution:
select column
from table
order by
LPAD(column, 10)
The LPAD function pads the left-side of the string with spaces so that the results will be sorted numerically. This works for non-numeric values, and null values will be sorted last. This works well if you know the maximum length of the strings to be sorted (you may need to adjust the second parameter to suit your needs).
Source: http://www.techonthenet.com/oracle/questions/sort1.php
EDIT:
I noticed that while my solution works well for my case, the output is slightly different from the accepted answer (http://www.sqlfiddle.com/#!4/d935b8/2/0):
1
1
10
11
11
12
31
100
110
114
300
A14
A18
4200
A170
(null)
(null)
4200 should come after 300. For my situation this is good enough, but this may not always be the case.
Based on the previous solution:
SELECT column
FROM table
ORDER BY LPAD(column, (SELECT MAX(LENGTH(column)) FROM table)) ASC
The advantage of this approach is that you don't need know the table column size.
i need to be able to get distinct values grouped by FileID and by SentToID
this is what i have now, and it only groups by SentToID, which is missing some records.
var sentByResults = from v in ctx.vEmailSents
where v.TypeDesc.Equals("Request")
group v by v.SentTo_ID into g
select g.OrderByDescending(x => x.DateSent).FirstOrDefault() into lastV
select new
{
ClaimID = lastV.Claim_ID,
SentToID= lastV.SentTo_ID,
};
so if i have 5 records
claim id fileid sentToID
1 15 27
1 16 27
1 15 26
1 15 26
1 15 47
right now i get 3 records back, one for each unique sentToID, but i need to get 4 records back, for each unique ID within each unique fileID
I suspect you just want to group by an anonymous type:
group v by new { v.SentTo_ID, v.FileID }
Also, given that you'll never get any empty groups, you should be able to use First instead of FirstOrDefault.
I have a list of timebased values in the following form:
20/Dec/2011:10:16:29 9
20/Dec/2011:10:16:30 13
20/Dec/2011:10:16:31 13
20/Dec/2011:10:16:32 9
20/Dec/2011:10:16:33 13
20/Dec/2011:10:16:34 14
20/Dec/2011:10:16:35 6
20/Dec/2011:10:16:36 7
20/Dec/2011:10:16:37 16
20/Dec/2011:10:16:38 5
20/Dec/2011:10:16:39 7
20/Dec/2011:10:16:40 15
20/Dec/2011:10:16:41 12
20/Dec/2011:10:16:42 13
20/Dec/2011:10:16:43 11
20/Dec/2011:10:16:44 6
20/Dec/2011:10:16:45 7
20/Dec/2011:10:16:46 9
20/Dec/2011:10:16:47 14
20/Dec/2011:10:16:49 6
20/Dec/2011:10:16:50 11
20/Dec/2011:10:16:51 15
20/Dec/2011:10:16:52 10
20/Dec/2011:10:16:53 16
20/Dec/2011:10:16:54 12
20/Dec/2011:10:16:55 8
The second column contains value against each second. Values are there for complete month and for each and every second. I want to add these values:
Per minute basis. [for 00 - 59 seconds ]
Per hour basis [ for 00 - 59 minutes ]
Per Day basis. [ for 0 - 24 hours ]
Sounds like a job for Excel and a pivot table.
The trick is to parse the text date/time you have into something Excel can work with; splitting it on the colon will do just that. Assuming the value you have is in cell A2, this formula will convert the text into a real date:
=DATEVALUE(LEFT(A2,SEARCH(":",A2)-1))+TIMEVALUE(RIGHT(A2,LEN(A2)-SEARCH(":",A2)))
Then just create Minute, Hour and Day columns where you subtract out that portion of the date. For example, if the date from the above formula is in C2, the following will subtract out the seconds and give you just up to the minute:
=C2-SECOND(C2)/24/60/60
Then repeat the process for the next two columns to give you the hour and the day:
=D2-MINUTE(D2)/24/60
=E2-HOUR(E2)/24
Then all you have to do is create a pivot table on the data with rows Day, Hour, Minute and value Sum(Value).