SQL Server equivalent of dense_Rank() and TO_DATE() of Postgres - sql-server

I have the below query coming from the Postgres database. I want to convert the below query from Postgres to an Azure SQL Server version.
I know that TO_DATE can be written as convert(DATETIME,...) but I want to protect the date format too. Even after changing TO_DATE, there are still errors. Can someone help me with this?
SELECT b.*
FROM (
SELECT MAX(gs.ID),
dense_rank() over (order by gs.TIME_COLUMN DESC ) AS latest
FROM TEST_TABLE gs
WHERE TIME_COLUMN BETWEEN TO_DATE('%time_parameter%', 'YYYY-MM-DD HH24:MI:SS')
AND TO_DATE('%time_parameter2%', 'YYYY-MM-DD HH24:MI:SS')
GROUP BY gs.OTHER_ID, gs.TIME_COLUMN
) a
LEFT JOIN TEST_TABLE b ON max.latest = b.ID

The equivalent to ensuring YYYY-MM-DD isn't incorrectly interpreted as YYYY-DD-MM in some languages is to explicitly specify a style number during the convert:
WHERE TIME_COLUMN
BETWEEN CONVERT(datetime, '%time_parameter%', 21)
AND CONVERT(datetime, '%time_parameter2%', 21)
For a full list of styles, see Build a cheat sheet for SQL Server date and time formats.
As Larnu and Panagiotis commented, it would be much better if you use a language-neutral format, like yyyy-MM-ddThh:mm:ss.nnn, and/or datetime2 in place of datetime, which will prevent language settings from interfering with datetime parsing.
And as an aside, BETWEEN should generally be avoided for date range queries; see the first couple of links at Dating Responsibly.

This is the SQL Server version of the above query. Thanks for the discussions but this one and a bit of trying solved the issue.
SELECT b.*
FROM (
SELECT MAX(gs.ID) as max,
dense_rank() over (order by gs.TIME_COLUMN DESC ) AS latest
FROM TEST_TABLE gs
WHERE TIME_COLUMN BETWEEN CONVERT(DATETIME, '%time_parameter%')
AND CONVERT(DATETIME, '%time_parameter2%')
GROUP BY gs.OTHER_ID, gs.TIME_COLUMN
) a
LEFT JOIN TEST_TABLE b ON a.max = b.ID

Related

Easier way to count users in T-SQL

I'm using this query in SQL Server 2016 to determine how many users have logged into my system.
The users.lastaccess column contains a unix timestamp, so I use DATEDIFF() to convert it to a yyyy-mm-dd hh:mm:ss date.
SELECT
COUNT(*) AS user_logins
FROM
(SELECT
ROW_NUMBER() OVER(ORDER BY lastaccess DESC) AS Row
FROM
users
WHERE
lastaccess > DATEDIFF(s, '1970-01-01 02:00:00', (SELECT Convert(DateTime, DATEDIFF(DAY, 0, GETDATE()))))
)
The result is a simple number, e.g. 75, representing the number of users who have been authenticated on the system.
The following code returns the count of users. It uses cast to drop the time-of-day from the value returned by GetDate and uses ISO 8601 for the base date/time of the unix system.
select Count(*) as User_Logins
from Users
where LastAccess > DateDiff( s, '1970-01-01T02:00:00', Cast( GetDate() as Date ) );
Why do you need a correlated subquery and a ROW_NUMBER() windowing function at all? And what is that oddball date-based WHERE clause? What are you really checking for - the fact that last_access is not null/empty??
Just use:
SELECT
COUNT(*) AS user_logins
FROM
dbo.users
WHERE
-- your WHERE condition isn't very clear - please add code as needed
-- but *DO NOT* convert dates to string to compare! Compare proper dates!
lastaccess IS NOT NULL
Also: if you have a non-nullable, narrow, fixed-width column in your dbo.Users table, you should have a nonclustered index on this (e.g. on lastaccess - is that column nullable?) - that could speed things up quite a bit

Oracle Linked Server in SQL Server 2012 - query with DATE column not working

Queries:
SELECT DISTINCT RCPCODE
FROM SMC..ICWGHC.C_JOBINFOHISTORY
WHERE UPDATE_DATETIME >= '2017-01-14 13:08:49.0000000'
AND UPDATE_DATETIME <= '2017-01-16 13:08:49.0000000'
SELECT DISTINCT RCPCODE
FROM SMC..ICWGHC.C_JOBINFOHISTORY
WHERE COMPLETE_DATETIME BETWEEN '2017-01-16 06:52:38.0000000'
AND '2017-01-16 12:52:38.0000000'
ORDER BY COMPLETE_DATETIME DESC
Both the queries with BETWEEN and ">=" did not work for condition in Date column.
If I use this query:
SELECT DISTINCT RCPCODE
FROM SMC..ICWGHC.C_JOBINFOHISTORY
it does return data.
I'd like to filter data with BETWEEN condition for retrieving data, so that I can sort with datetime.
I have a similar situation with an Oracle linked server in SQL Server. I had not used the syntax you have since we usually use OPENQUERY for this sort of thing so I thought I would give it a try.
There is some sort of issue with the string to date conversion that implicitly happening. Try this...
SELECT DISTINCT RCPCODE
FROM SMC..ICWGHC.C_JOBINFOHISTORY
WHERE COMPLETE_DATETIME BETWEEN CONVERT(DATETIME, '2017-01-16 06:52:38', 121)
AND CONVERT(DATETIME, '2017-01-16 12:52:38', 121)
ORDER BY COMPLETE_DATETIME DESC
Note that I removed the trailing zeros from the date/time string. They were causing me trouble.
Here is what you would do to use OPENQUERY to do a passthrough query to Oracle...
SELECT *
FROM OPENQUERY(SMC, '
SELECT DISTINCT RCPCODE
FROM ICWGHC.C_JOBINFOHISTORY
WHERE COMPLETE_DATETIME BETWEEN ''2017-01-16 06:52:38''
AND ''2017-01-16 12:52:38''
ORDER BY COMPLETE_DATETIME DESC')
I again removed the trailing zeros.
Do either of those work for you?
Noel

Arithmetic overflow error converting expression in to data type datetime

Hoping someone can help. I've looked on the internet for a solution but none seem to resolve it.
I want to query a large table and only get the results back where a column equals today's date.
Here's the query:
select [Table1].[Field1]
from [Table1]
where [Table1].[Field1] = GetDate()
The date format is as follows:
20020630
I'm a beginner in SQL so any help would be really appreciated because I am growing fond of it.
Thank you!!! :)
To find the broken value:
select [Table1].[Field1]
from [Table1]
where ISDATE([Table1].[Field1]) = 0
GETDATE includes a time, so you need to remove this. This assumes SQL Server 2008+
select [Table1].[Field1]
from [Table1]
where [Table1].[Field1] = CAST(GetDate() AS date)

Issues with SQL Server LIKE clause

I'm sure this is a VERY simple problem, but I've not been able to figure it out. Here's my query:
select column1 from table1 with(nolock)
where column1 like '2011-07-0[78]%'
order by column1 desc
As you can tell, I'm querying a row looking for timestamps that are from either today or yesterday.
A full timestamp within one of these rows looks like this:
2011-07-08 12:16:39.553
I've done similar things many times with no trouble, but the above query returns no results no matter what I try. (Yes, there are timestamps from today and yesterday in the column).
Have I made a syntax error? Am I crazy? Are there gnomes in my DB messing with my query? Please help! Thank you so much!
If the datatype for that field is datetime or smalldatetime then LIKE won't work as expected.
You could do a DATEPART function or BETWEEN, like:
WHERE DATEPART(Year, column1) = 2011
AND DATEPART(Month, column1) = 7
AND DATEPART(Day, column1) IN (7, 8)
or
WHERE column1 BETWEEN '2011-07-07' AND '2011-07-08'
Bear in mind BETWEEN is inclusive.
try this :
select column1 from table1 with(nolock)
where Cast(column1 as DateTime) between '2011-07-07' AND '2011-07-08'
order by column1 desc

Problem with creating Indexed View AND Group BY in SQL Server 2008 R2

I want to create indexed view with such t-sql:
Select
Table1_ID,
cast(CONVERT(varchar(8),
t2.Object_CreationDate, 112)AS DateTime) as Object_CreationDate ,
Count_BIG(*) as ObjectTotalCount
from
[dbo].Table2 t2 inner join [dbo].Table1 t1 on ...
Group BY
Table1_ID, CONVERT(varchar(8), t2.Object_CreationDate, 112))
I need to make group by only by datepart of column Object_CreationDate (type datetime2 ).
Also I want to set index on columns Theme_Id AND Object_CreationDate in the derived view.
If I use cast(CONVERT(varchar(8), m.Mention_CreationDate, 112)AS DateTime) in SELECT - I'll get problems with index on this column. Because this column (Object_CreationDate) is not deterministic.
I wonder if it is possible to solve a problem.
replace ...
CONVERT(varchar(8), t2.Object_CreationDate, 112))
... with
DATEADD(day, DATEDIFF(day, 0, t2.Object_CreationDate), 0)
--OR
CAST(t2.Object_CreationDate AS date)
The 2nd format is SQL Server 2008+ only, the 1st is more general
This removes the time component from a datetime value in the date/datetime datatype domain without any intermediate locale dependent datetime formats
See these answers: One and Two(comments)

Resources