Computed time column in SQL Server - asp.net

Using vs2008 I have a SQL Server database attached to my web app. I want to use a computed time column in the database, along the lines of :
timenow is 1 column
hoursleft is another column
timeend would be another column.
I want timeend to = timenow + hoursleft.
Is it possible to do that, and if so what would the formula be that I would enter into the computed column field, and, what datatype would the columns be, timenow and timeend I would expect to be time(7) and hoursleft an int. But is that correct? THanks for any help.

TimeNow is datatype datetime, populated with function GetUtcDate().
HoursLeft is an int, populated as required.
TimeEnd is a computed column of type datetime, computed as DateAdd(hh, HoursLeft, TimeNow).

You'd use this to calculate timeend from the 2 existing columns hoursleft and timenow
CAST(DATEADD(hour, hoursleft, timenow) AS time(7))
DATEADD return type is
The return data type is the data type of the date argument
So the explicit CAST probably isn't needed if timenow is time(7) as you mentioned
DATEADD(hour, hoursleft, timenow)

Related

Performing calculations based on multiple entries of data being fed from ViewModel

I'm having a bit of difficulty figuring out how to approach this function.
I have an SQLite database that is being handled by room, and I need to update entries in sharedpreferences based on this data. There is already a dao query setup to give entries by descending order of datetime:
#Query("SELECT * FROM data_table ORDER BY datetime DESC")
LiveData<List<Data>> getAllData();
These datetimes have corresponding float entries that I have to perform cumulative calculations on based on the difference of time to the next data entry's datetime. So, for example:
id datetime float
1 dt(1) 12.0f
2 dt(2) 15.0f
2 dt(3) 13.0f
I would start with
var timeDiff = ((Duration.between(LocalDateTime.parse(dt(1)),LocalDateTime.parse(dt(2)).toMillis())/1000).toFloat()
var currentValue = [big complicated formula applied to 12.0f based on timeDiff]
and then I would move on to
currentValue = (currentValue + 15.0f)
timeDiff = ((Duration.between(LocalDateTime.parse(dt(2)),LocalDateTime.parse(dt(3)).toMillis())/1000).toFloat()
currentValue = [big complicated formula applied to previous currentValue based on timeDiff]
until I get to the last entry, where I store that datetime and currentValue as a sharedpreference.
I'm not really sure how to go about this though. I was thinking of using a mutable array list:
mDataViewModel = ViewModelProvider(this).get(DataViewModel::class.java)
var tarray: MutableList<List<Data?>?> = ArrayList()
mDataViewModel.getAllData().observe(this, Observer<List<Data>>() {
fun onChanged(data: List<Data?>?) {
tarray.add(data)
}
})
Toast.makeText(this#MainActivity, tarray.toString(), Toast.LENGTH_SHORT).show()
and then performing the calculations on the list sequentially, but it doesn't appear to be populating. I would much prefer to perform the cumulative calculations as they're fed from the database. This is my first time using SQlite though, and I'm not there is a much easier way of accomplishing this than what I'm attempting to do. Any advice would be greatly appreciated.
I would much prefer to perform the cumulative calculations as they're fed from the database. This is my first time using SQlite though, and I'm not there is a much easier way of accomplishing this than what I'm attempting to do. Any advice would be greatly appreciated.
Perhaps consider the following as a pointer which may be along the lines of what you are trying to accomplish. That is getting the data you want from the database.
/* Create the TEST ENVIRONMENT */
DROP TABLE IF EXISTS data_table;
CREATE TABLE IF NOT EXISTS data_table (id INTEGER PRIMARY KEY, datetime TEXT, float REAL);
INSERT INTO data_table (datetime,float) VALUES('2021-04-01 12:00',12.0),('2021-04-01 13:00',15.0),('2021-04-01 16:00',13.0);
/* Show the raw/actual data */
SELECT * FROM data_table;
/* now extract the useful data */
WITH y AS (
SELECT
datetime,
float,
/* Get the float value of the previous row (as first would be NULL use COALESCE get the current float value )*/
COALESCE(
(SELECT float FROM data_table WHERE datetime < x.datetime ORDER BY datetime DESC LIMIT 1 ),x.float
) AS prev_float,
COALESCE(
(SELECT datetime FROM data_table WHERE datetime < x.datetime ORDER BY datetime DESC LIMIT 1 ),
(SELECT datetime FROM data_table ORDER BY datetime ASC LIMIT 1)
) AS prev_datetime
FROM data_table AS x
)
SELECT datetime, prev_datetime, strftime('%s',datetime) - strftime('%s',prev_datetime) AS datediff_in_seconds, float, float-prev_float as floatdiff FROM y ORDER BY datetime ASC;
DROP TABLE IF EXISTS data_table; /* clean-up the testing environment */
So you start off with the following data as an example :-
And it produces :-
i.e. the manipulated data
Note the use of COALESCE to return previous values for the first row. COALESCE returns the first non-null value of the listed values. The first being the value from the previous row, which would be null for the first row so it gets the current value
in the case of the date time, datetime could have been used however as cab be seen a sub query has been used just to demonstrate the flexibility of SQlite SQL.
It's then just a matter of two additional steps for Room :-
Create the Dao query using the complex query (from the WITH .... to the SELECT .... FROM y ORDER BY datetime ASC; )
Create a suitable POJO class/data class. For the example/pointer given you'd have var's or val's for
datetime
prev_datetime
datediff
float
prev_float
floatdiff
as these are the columns returned.
This isn't really about the database or the LiveData, right? You just want a way to run through this set of data?
You could use zipWithNext to turn the data into a list of Pairs, and run a fold on that. You gave an example of how you'd handle the first case, and how you'd handle every case after that, but really they're all
currentValue = currentValue + data1's float
timeDiff = time difference between data1 and data 2
currentValue = something based on currentValue and timeDiff
where currentValue starts off as 0, so on your first run it's currentValue = 0f + 12.0f
Here's how you can do that with a fold:
// Just a basic version of the data you're working with, as a demo
data class Thing(val time: DateTime, val number: Float)
typealias DateTime = Int
val stuff = listOf(Thing(10, 12.0f), Thing(12, 15.0f), Thing(15, 17.0f))
fun main() {
stuff.zipWithNext().fold(0f) { currentValue, (data1, data2) ->
val timeDiff = data2.time - data1.time
val newValue = complicatedTask(currentValue + data1.number, timeDiff)
newValue
}
.run(::println)
}
fun complicatedTask(number: Float, timeDiff: Int) = number * timeDiff
>> 117.0
The accumulator you're folding through is that currentValue float, so you start with 0f and return the new value at the end of the fold function, and that's what pops out at the end.
If you want the datetime too, you can make that part of the accumulator - I'm just gonna reuse that data class but you can make your own, or use a basic Pair or whatever:
stuff.zipWithNext().fold(Thing(0, 0f)) { (_, currentValue), (data1, data2) ->
val timeDiff = data2.time - data1.time
val newValue = complicatedTask(currentValue + data1.number, timeDiff)
Thing(data1.time, newValue)
}
>> Thing(time=12, number=117.0)
Using a start value with time=0 (gotta have something), and at the end of the function you're returning the first datetime, i.e. d(1) when you're comparing d(1) and d(2). You could return the other one if that's what you wanted. I just gave it an anonymous _ variable name in the function because you don't actually use it in there, you only care about it when it pops out as the result.
I'm not sure if that helps with what you're doing - if you want to keep running this process every time a new value is observed (maybe that's why you want the datetime in the result?) you could make the lambda a separate function, that way the fold can call it, but you can also use it yourself for one-off updates when you get some new data. And you can use that result as the start value for a new fold, if you need to run it on a bunch more values. Hope that makes sense!

extract date time then compare with previous datetime

I want to make sure the date time stored in database table is not more than 2 minutes than previous captured date time.
the result returned from Database table is in this format.
[[col1:2020-05-28 04:02:21.34]]
my codes
import java.text.SimpleDateFormat
//capture current date time
def date = new Date()
println date.format('yyyy-MM-dd hh:mm:ss.SS',TimeZone.getTimeZone('UTC'))
//wait 2 minutes then capture DB table date time
WebUI.delay(120)
PostgresdbQuery = /SELECT col1 FROM table1.test/
List resultsafter = CustomKeywords.'test.database.getPostgresSQLResults'(GlobalVariable.testPostgresdbConnString , GlobalVariable.testPostgresdbUsername , GlobalVariable.testPostgresdbPassword ,GlobalVariable.testPostgresdbDriver ,PostgresdbQuery )
println(resultsafter)
//assert
assert resultsafter < date, 'Execute time is within 2 minutes'
error
Reason:
groovy.lang.GroovyRuntimeException: Cannot compare java.util.ArrayList with value '[{col1=2020-05-28 04:02:21.34}]' and java.util.Date with value '5/28/20 1:49 PM'
The result is a list of maps. To make that check work, you would have to write it as:
assert resultsAfter.first().col1 < date
This will only work for the very first result and only if there is one. Assuming, you want to assert that for all elements, you can use every or loop the results and do the asserts for each row.
Yet, at this point i'd just let the DB do the work: select all items, that dont't match the criteria and make sure, no results are found.

Compare date part of datetime column with NamedQuery

I have a table containing entries with date and time. I try to create a NamedQuery which only compares the date part.
#NamedQuery(name = "Vote.findForDate", query = "SELECT v FROM Vote v WHERE v.createdAt = :date")
...
createNamedQuery("Vote.findForDate").setParameter("date", date, TemporalType.DATE).getResultList();
But it seems that it always tries to compare the whole datetime.
Is there no way without using date() function in SQL?
I try to be independent from the database. For example h2 has no date() function.
One possible solution is the usage of date as column type and reduce the information.
#Column(name = "voteDate")
#Temporal(value = TemporalType.DATE)
private Date voteDate;

How can I remove the Time from a DateTime value?

In my SQL database, I have a column formatted as DateTime and when I retrieve data from that column in ASP.NET, I catch it on the Date variable, than pass the value to textbox:
Dim Y As Date = dt.Rows(0)("SCH_DATE")
txtSchedDate.Text = Y.Date.ToString
but when I debug my website, the txtSchedDate.Text still gives me the full DateTime value:
7/17/2013 12:00:00 AM
is it possible to eliminate the time value here and just return the date?
Have you tried using something like
txtSchedDate.Text = Y.Date.ToString("MM/dd/yyyy")
or which ever format you wish to display.
Have a look at
DateTime.ToString Method (String)
Converts the value of the current DateTime object to its equivalent
string representation using the specified format.
Custom Date and Time Format Strings
Standard Date and Time Format Strings
Convert.ToDateTime(dt.Rows(0)("SCH_DATE")).ToString("M/d/yyy")
you can get date by txtSchedDate.Text = Y.Date.ToShortDateString()
Besides answers above, you can try converting it in SQL server
SELECT CONVERT(varchar(15), GETDATE(), 11)
Keep in mind after converting it's VARCHAR(15) instead of DATETIME.
Once you have a Date object, you can get the constituent pieces if you wish as well, like this:
Dim Y As Date = dt.Rows(0)("SCH_DATE")
txtSchedDate.Text = Y.Date.Year & "-" & Y.Date.Month & "-" & Y.Date.Day
Or you can use the custom and standard date and time format strings mentioned by others.

Date comparision using Linq

I have a DateTime type column named "CreatedDate" in my sql table, and am passing the value for this column by using "DateTime.Now" from my asp.net application....
The datas in my CreatedDate column are,
CreatedDate
-----------
2012-05-07 18:56:17.487
2012-05-07 18:56:28.443
2012-05-07 19:21:24.497
2012-05-14 15:22:04.587
I need to get the datas with this CreatedDate.
in my entity framework I tried the condition like
DataAccess.Entities dataEntities = new DataAccess.Entities();
DataAccess.Employee employee = dataEntities.Employees
.First(e => e.CreatedDate == DateTime.Today);
like this, I have data for this date(2012-05-14) , but the mininutes part differes (the DateTime.Today gives '2012-05-14 12:00:000' like this) here, and it shows error like, sequence contains no element....
How can I compare the 'Date' alone in Linq.....can anyone help me here,,,
Use the Date Property on the DateTime object
CreatedDate.Date==DateTime.Today
So your code will be
DataAccess.Employee employee=dataEntities.
Employees.First(e=>e.CreatedDate.Date==DateTime.Today);
Date Property returns the Date Component of the DateTime object and the time value set to 12:00:00 midnight (00:00:00).
Try this:
DataAccess.Employee employee =
dataEntities.Employees.First(e=>e.CreatedDate.Date==DateTime.Today)
I just declared two variable like
DateTime date1=DateTime.Now.Date;
DateTime date2=DateTime.Now.Date.AddDays(1);
and in the condition I used these variables like
DataAccess.Employee employee = dataEntities.Employees
.First(e => e.CreatedDate >= date1
&& e.CreatedDate < date2);
its working....

Resources