mariadb FROM_UNIXTIME future times limitation - mariadb

A note for anyone else hitting the same problem. In MariaDB the FROM_UNIXTIME function has a limit to how far into the future it will allow. DateTime fields and the DATE_ADD functions don't have this limit.
MariaDB> SELECT FROM_UNIXTIME(2155507200) ;
+---------------------------+
| FROM_UNIXTIME(2155507200) |
+---------------------------+
| NULL |
+---------------------------+
1 row in set (0.00 sec)
MariaDB> SELECT DATE_ADD("1970-01-01 00:00:00", INTERVAL 2155507200 SECOND) ;
+-------------------------------------------------------------+
| DATE_ADD("1970-01-01 00:00:00", INTERVAL 2155507200 SECOND) |
+-------------------------------------------------------------+
| 2038-04-22 00:00:00 |
+-------------------------------------------------------------+
1 row in set (0.00 sec)

TIMESTAMP runs out in 2038, by which time all the computers and software you are using will be recycled and replaced. If you doubt it, think about what computer stuff you still have from 18 (= 2038-2020) years ago. Zip. Nada.
DATETIME lasts until 9999-99-99, a long time from now.

Related

I need a conversion function, from integer to date-time

Is there a conversion to go from an integer (ex: 54600) to date-time format? I am seeing the integers in a flowsheet in healthcare, used to record a time
CONVERT(varchar, DATEADD(ms, b22.meas_value * 1000, 0), 114) AS 'START TIME' : Is the code that worked in MS SQL, but SNOWFLAKE does not recognize the function.
You can try to use TO_DATE. The data type of the returned value is DATE.
Syntax
TO_DATE( '<integer>' )
where
<integer>
An expression that evaluates to a string containing an integer, for example ‘15000000’. Depending upon the magnitude of the string, it can be interpreted as seconds, milliseconds, microseconds, or nanoseconds.
For details or other usage, see the above link.
There are a few different ways:
select 1637804567::varchar::date as date;
+------------+
| DATE |
|------------|
| 2021-11-25 |
+------------+
select to_date(1637804567::varchar) as date;
+------------+
| DATE |
|------------|
| 2021-11-25 |
+------------+
TO_DATE or CASTING will require the value to be string, so you need to convert the integer to string first before converting to date.
For your example, it will be like below in Snowflake:
select dateadd(ms, 54600*1000, to_date(1637804567::varchar)) as date;
+-------------------------------+
| DATE |
|-------------------------------|
| 2021-11-25 15:10:00.000000000 |
+-------------------------------+
TRY_TO_TIME() (there's a joke in there somewhere)
select try_to_time('54600') AS "START TIME"

Calculate Count of users every month in Kusto query language

I have a table named tab1:
Timestamp Username. sessionid
12-12-2020. Ravi. abc123
12-12-2020. Hari. oipio878
12-12-2020. Ravi. ytut987
11-12-2020. Ram. def123
10-12-2020. Ravi. jhgj54
10-12-2020. Shiv. qwee090
10-12-2020. bob. rtet4535
30-12-2020. sita. jgjye56
I want to count the number of distinct Usernames per day, so that the output would be:
day. count
10-12-2020. 3
11-12-2020. 1
12-12-2020. 2
30-12-2020. 1
Tried query:
tab1
| where timestamp > datetime(01-08-2020)
| range timestamp from datetime(01-08-2020) to now() step 1d
| extend day = dayofmonth(timestamp)
| distinct Username
| count
| project day, count
To get a very close estimation of the number of Usernames per day, just run this (the number won't be accurate, see details here):
tab1
| summarize dcount(Username) by bin(Timestamp, 1d)
If you want accurate results, then you should do this (just note that the query will be less performant than the previous one, and will only work if you have up to 1,000,000 usernames / day):
tab1
| summarize make_set(Username) by bin(Timestamp, 1d)
| project Timestamp, Count = array_length(set_Username)

MariaDB : Trigger keeps getting syntax error after insert

I have two tables. Table vitamin contains column vitamin_name and price. Table vitamin_variety contains columns price_variety and price_variety_extreme. I want to create an AFTER INSERT Trigger, that will insert the price of vitamin if the value of vitamin_name contains extreme into price_variety_extreme and not contains extreme into price_variety .
Here's what I mean if I insert this into vitamin, the price will be input into vitamin_variety
table = vitamin
+----------------+-------+
| vitamin_name | price |
+----------------+-------+
| extreme pill 1 | 10 |
| pill 1 | 5 |
| extreme pill 2 | 20 |
| pill 2 | 10 |
+----------------+-------+
table = vitamin_variety
+---------------+-----------------------+
| price_variety | price_variety_extreme |
+---------------+-----------------------+
| 5 | 10 |
| 10 | 20 |
+---------------+-----------------------+
my query keeps getting syntax error. it keeps saying
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use
near '' at line 5
what's wrong?
create trigger vitamin_ain after insert on vitamin
for each ROW
if vitamin.vitamin_name like 'extreme%' then
update vitamin_variety
set price_variety_extreme = new.price_variety_extreme;
else if vitamin.vitamin_name not like 'extreme%' then
update vitamin_variety
set price_variety = new.price_variety;
end if;
There are some syntax issues, and other situations, but the conditions inside the trigger could look like the code below:
First, (not right or wrong) the else if could be simplified to an else. If the first condition finds extreme, there is no need to inverse check for not like extreme. (unless some strange requirement expects that handling)
Of course, feel free to keep the else if check as-is, if it makes more sense to you, but I used this code:
if new.vitamin_name like 'extreme%' then
update vitamin_variety
set price_variety_extreme = new.price;
else
update vitamin_variety
set price_variety = new.price;
end if
The 'syntax issues':
In the if condition, change vitamin.vitamin_name to new.vitamin. Columns from trigger insert actions are referenced from new, not the table name.
If keeping your original else if, need to change the same vitamin.vitamin_name reference mentioned in item 1.
References new.price_variety_extreme and new.price_variety do not exist from the vitamin insert (these columns are not in vitamin), but new.price is, and the other vitamin columns.
The 'other situations':
Without any rows already present in the vitamin_variety table, no update will occur, because there are not any rows to update. This situation will make it seem as if the trigger is not working, but there is nothing for the trigger to update.
The desired output to vitamin_variety cannot be achieved with the current info. The update will set ALL columns of one or the other to the last inserted price, because there is no unique row reference. (no WHERE clause to limit what row(s) get updated)
Here's some sample interaction:
As the first other situation mentioned, there are no rows in the vitamin_variety table, so I added one:
MariaDB [test]> insert into vitamin_variety (price_variety, price_variety_extreme) values (0, 0);
Query OK, 1 row affected (0.08 sec)
MariaDB [test]> select * from vitamin_variety;
+----+---------------+-----------------------+
| id | price_variety | price_variety_extreme |
+----+---------------+-----------------------+
| 1 | 0 | 0 |
+----+---------------+-----------------------+
1 row in set (0.00 sec)
Then, with the trigger added to vitamin, inserted a couple of rows:
MariaDB [test]> insert into vitamin( vitamin_name, price ) values ('pilly 5', 7);
Query OK, 1 row affected (0.10 sec)
MariaDB [test]> insert into vitamin( vitamin_name, price ) values ('extreme pill 5', 3);
Query OK, 1 row affected (0.12 sec)
Show those inserts:
MariaDB [test]> select * from vitamin;
+----+----------------+-------+
| id | vitamin_name | price |
+----+----------------+-------+
| 8 | pilly 5 | 7 |
| 9 | extreme pill 5 | 3 |
+----+----------------+-------+
2 rows in set (0.00 sec)
Show the triggered price updates to the vitamin_variety table:
MariaDB [test]> select * from vitamin_variety;
+----+---------------+-----------------------+
| id | price_variety | price_variety_extreme |
+----+---------------+-----------------------+
| 1 | 7 | 3 |
+----+---------------+-----------------------+
1 row in set (0.00 sec)
=====
EDIT:
One possible way to achieve your goal, given this vitamin_variety table structure:
CREATE TABLE `vitamin_variety` (
`pill_name` varchar(25) NOT NULL,
`price_variety` int(11) NOT NULL DEFAULT '0',
`price_variety_extreme` int(11) NOT NULL DEFAULT '0',
UNIQUE KEY `pill_name` (`pill_name`)
);
Then changing the vitamin table trigger conditions to:
if new.vitamin_name like 'extreme%' then
insert into vitamin_variety (pill_name, price_variety_extreme)
values (replace(new.vitamin_name, 'extreme ', ''), new.price)
on duplicate key update price_variety_extreme = new.price;
else
insert into vitamin_variety (pill_name, price_variety)
values (new.vitamin_name, new.price)
on duplicate key update price_variety = new.price;
end if
Then running insert SQL based on your original vitamin table details:
MariaDB [test]> insert into vitamin (vitamin_name, price) values ('extreme pill 1', 10);
Query OK, 1 row affected (0.09 sec)
MariaDB [test]> insert into vitamin (vitamin_name, price) values ('pill 1', 5);
Query OK, 1 row affected (0.16 sec)
MariaDB [test]> insert into vitamin (vitamin_name, price) values ('extreme pill 2', 20);
Query OK, 1 row affected (0.10 sec)
MariaDB [test]> insert into vitamin (vitamin_name, price) values ('pill 2', 10);
Query OK, 1 row affected (0.10 sec)
Gives:
MariaDB [test]> select * from vitamin_variety;
+-----------+---------------+-----------------------+
| pill_name | price_variety | price_variety_extreme |
+-----------+---------------+-----------------------+
| pill 1 | 5 | 10 |
| pill 2 | 10 | 20 |
+-----------+---------------+-----------------------+
2 rows in set (0.00 sec)

T-SQL Server ORDER BY date and nulls last

I am studying for exam 70-761 and there is a challenge asking to place nulls in the end when using order by, I know the result is this one:
select
orderid,
shippeddate
from Sales.Orders
where custid = 20
order by case when shippeddate is null then 1 else 0 end, shippeddate
what i don't know is why the 1 and 0 and how they affect the result can anyone clarify.
Best Regards,
Daniel
There are two parameters in your order clause, it like to split two groups and then continue sort items inside those groups
First, because 0 less than 1, so all the orders without shippeddate will be push to last.
Then we will order by shippeddate
Example:
orderID | shippeddate
| null
| today
| null
| yesterday
| tomorrow
First sort by case when shippeddate is null then 1 else 0 end we will got
orderID | shippeddate
| today
| yesterday
| tomorrow
| null
| null
then continue sort with shippeddate, we will got
| yesterday
| today
| tomorrow
| null
| null
hope it useful to you

SQLite: Select row based on time of day?

I have a SQLite table like the following:
+-----------+-------+
| StartTime | Name |
+-----------+-------+
| 08:00:00 | zone1 |
| 13:00:00 | zone2 |
| 17:30:00 | zone3 |
| 22:00:00 | zone4 |
+-----------+-------+
I'm trying to write a query that will return the row based on the current time:
If CurrentTime is 08:30 it will return zone1
If CurrentTime is 16:40 it will return zone2
If Currenttime is 04:01 it will return zone4
and so on...
So far I had some luck but not exactly what I wanted
SELECT * FROM table WHERE StartTime >= time('now', 'localtime')
ORDER BY StartTime LIMIT 1;
I've tried some variations of the above statement, but none returns the result I'm after.
Thanks!
You'll make your life a lot easier if you add an "EndTime" field as well, as you can then simply check if the current time is within the start and end time.
For example, if your database table consisted of the following...
+-----------+----------+-------+
| StartTime | EndTime | Name |
+-----------+----------+-------+
| 08:00:00 | 12:59:59 | zone1 |
| 13:00:00 | 17:29:59 | zone2 |
| 17:30:00 | 21:59:59 | zone3 |
| 22:00:00 | 07:59:59 | zone4 |
+-----------+----------+-------+
...you could simply use a query along the lines of:
SELECT Name FROM table WHERE StartTime >= time('now', 'localtime')
AND EndTime <= time('now', 'localtime')
ORDER BY StartTime LIMIT 1;
Have you tried a having clause?
SELECT * FROM table WHERE StartTime >= time('now', 'localtime')
HAVING StartTime = MIN(StartTime)
Two versions.
This is the easiest to understand, but it assumes that max(Name) is meaningful. That is, it assumes that the values in "Name" are ordered from low to high.
SELECT max(Name)
FROM yourtable
WHERE StartTime< time("16:40:00");
This version uses a scalar subquery. It doesn't depend on any meaningful order to the names. I'd consider this version to be more robust.
SELECT Name
FROM yourtable
WHERE StartTime = (SELECT max(StartTime)
FROM yourtable
WHERE StartTime < time("16:40:00")
);
You'll want to replace the time()
literals with
time('now','localtime') in
production.
Expect an empty set if you run any of
these queries before 08:00 local
time.

Resources