What is the suggested date format to use in SQL Server? - sql-server

I've seen a few variations of writing dates in SQL Server as it doesn't support the more standard literal format of:
DATE '2014-01-01'
Is there a suggested way to write date-literals (or the closest thing to it) in SQL Server? Currently what I do is:
CAST('2014-01-01' AS date)
Whenever I want to use a date. Is this the most common?

SQL Server supports some date formats, but you can use '20220101'
CREATE TABLE t1([date] date)
INSERT INTO t1 values ('20220101')
SELECT * FROM t1
| date |
| :--------- |
| 2022-01-01 |
db<>fiddle here
You are misunderstanding SQL for TSQL.
In your SELECT date, '20220101' FROM t1the second is a string for SQL.
But as you see in the query below, TSQL will converts the text into a date automatically when comparing for example
SELECT CASE WHEN CAST('2014-01-01' AS date) > '20220101' THEN 'TRUE' ELSE 'FALSE' END
| (No column name) |
| :--------------- |
| FaLSE |
db<>fiddle here

Related

Supabase create sql function with count and group by

I'm having trouble figuring out this sql-function for Supabase.
create or replace function get_dates(user_id_input uuid, friend_id_input uuid)
returns setof available_dates
language sql
as $$ 
SELECT date, COUNT(date)
FROM available_dates
where user_id = (user_id_input)
or user_id = (friend_id_input)
GROUP BY date
HAVING COUNT(date) > 1;
$$;
All I get now is the error: Failed to run sql query: syntax error at or near " ".
I've tried some simpler ones and got them to work. The sql-query itself works outside of the function. It seems the trouble starts when I'm trying to use COUNT and GROUP BY. I've tried some with the placeholders as well (user_id_input uuid, friend_id_input uuid), so I don't think that's the problem.
My table looks like:
id| date |user_id
1 | 2022-08-08 | 8888888888
2 | 2022-08-08 | 4444444444
3 | 2022-08-04 | 8888888888
4 | 2022-08-06 | 4444444444
What I want from my query is the dates from the specific users where the dates are the same. When i run the pure sql-query I get:
date | count
2022-08-08 | 2
Does anyone see whats wrong with this?
Just a wild guess, so sorry if my suggestion does not work.
You set the return type of the function as setof available_dates, which means the return type must match the table schema of available_dates, but in the actual data that you are returning, you don't have a date column, but instead have a int column. At least that could be one reason of not working. You can just return setof records instead to remove this error.
create or replace function get_dates(user_id_input uuid, friend_id_input uuid)
returns setof records
language sql
as $$
SELECT date, COUNT(date)
FROM available_dates
where user_id = (user_id_input)
or user_id = (friend_id_input)
GROUP BY date
HAVING COUNT(date) > 1;
$$;

change the data format from ddmmyyyy to dd-mm-yyyy in snowflake

I am working on snowflake query where I am having a column(DATE) having data in form of ddmmyyyy(20211117 00:00:00). I need to convert this data into dd-mm-yyyy(2021-11-17 00:00:00.000
) format. I used the TO_DATE(DATE,'YYYY-MM-DD') expression but it doesn't work for me. Can somebody help me on this issue
TO_DATE will only return date portion, as below -
select to_date('20211117 00:00:00','yyyymmdd hh24:mi:ss') as date_col;
+------------+
| DATE_COL |
|------------|
| 2021-11-17 |
+------------+
Use TO_TIMESTAMP to get time portion as well -
select to_timestamp('20211117 00:00:00','yyyymmdd hh24:mi:ss') as datetime_col;
+-------------------------+
| DATETIME_COL |
|-------------------------|
| 2021-11-17 00:00:00.000 |
+-------------------------+
Refer Date examples
Refer Time Examples

Average in seconds of difference between timestamp cross db

I have two columns of timestamps in a table and I want to get the average of their difference. An example could this:
| start_date | end_date |
---------------------------------------------
| 2022-01-01 12:00:00 | 2022-01-01 13:00:00 |
| 2022-01-02 10:00:00 | 2022-01-02 12:00:00 |
| ... | ... |
|___________________________________________
I need the average to be expressed in seconds and I know that in postgresql you can do it like this:
select
exctract(epoch from avg(end_date - start_date)) as average
from
tableA
but in sqlServer you do it this way:
select
DATEDIFF(second, start_date, end_date) as average
from
tableA
I need to make a query that does this average but that uses ANSI sql, so no matter which db i encounter, i always get the same result.
My complete query looks like this:
select
name, description, .. as average
from
tableA, tableB, tableC
where
.... /* join conditions etc */
group by
name, description
Is there a way to do this? I'm not an expert but if functions could be useful in this scenario that is fine. I didn't come up a solution though.
The most imprtant DBs I work with are postgresql, oracle, mysql, sqlserver.

How to forecast count based on a day?

I am new to SQL Server world. I have a table as below:
alert_id | create_date | Status
---------+-------------+---------
1231 | 4/15/2017 | Open
1232 | 4/15/2017 | Open
1234 | 4/15/2017 | Closed
1235 | 4/16/2017 | Open
All of these alerts should be closed in 30 days. I need to get a forecast report which shows how many alerts are open for past 30 days.
I would like to write a select query whose output would be 2 columns. First would be Date and 2nd would be count. The date column should display all the dates for next 30 days and Count column should display the number of records which are due to expire on that day. Something like below would work. Please assist.
date | Count
----------+---------
5/15/2017 | 2
5/16/2017 | 3
5/17/2017 | 0
5/18/2017 | 0
.
.
.
6/14/2017 | 0
This is a job for GROUP BY and date arithmetic. In MySQL:
SELECT DATE(create_date) + INTERVAL 30 DAY expire_date, COUNT(*) num
FROM tbl
WHERE status = 'Open'
GROUP BY DATE(create_date)
DATE(create_date) + INTERVAL 30 DAY gets you the create date values with thirty days added.
GROUP BY(create_date) groups your data by values of your create date, truncated to midnight.
And, COUNT(*) goes with GROUP BY to tell you how many records in each group.
Edit In recent versions of SQL Server (MS)
SELECT DATEADD(day, 30, CAST(create_date AS DATE)) expire_date, COUNT(*) num
FROM tbl
WHERE status = 'Open'
GROUP BY CAST(create_date AS DATE)
Notice, please, that date arithmetic varies between make and model of SQL server software. That's why you get hassled by Stack Overflow users in comments when you use more than one tag like [oracle] [mysql] [sql-server] on your questions.
Cool, huh? You should read up on aggregate queries, sometimes called summary queries.
You're not going to get the missing dates with zeros by them. That's quite a bit harder to do with SQL.

Automatic update of values in SQL Server

For example I have a table tb with columns :
order_id | date_ordered | due_date | status
Are there any out of the box solution where I can automatically update status column when the current time (from server) reaches the value of the due_date column? How do I do it?
Thanks in advance.
UPDATE :
Something like this :
test1 | 2016-03-30 09:19:06.610 | 2016-03-30 11:19:06.610 | NEW
test2 | 2016-03-30 09:22:43.513 | 2016-03-30 11:22:43.513 | NEW
test3 | 2016-03-30 09:06:03.627 | 2016-03-30 11:06:03.627 | NEW
When the server time reaches 2016-03-30 11:19:06.610, test1's status will change value say, overdue
It depends on what you mean by "out of the box solution". You could create a sql server agent job, which checks every minute if the value due_date is less or equal to the current date and time and change the state column.
A computed column might be another, much simpler solution.
A table like this might suffice:
CREATE TABLE tb_test (
order_id INT PRIMARY KEY,
date_ordered DATETIME,
due_date DATETIME,
[status] as
CASE WHEN due_date <= GETDATE() THEN 'overdue'
ELSE 'new' END
);

Resources