SQL Server Sorting Date With Hours/Mins - sql

I have a complex date column that I need to sort by in SQL Server 2008
My query:
SELECT
DivisionName AS Division, StoreNum AS Store,
LeadName AS Lead, Type, ChangeType, Changes,
UpdatedBy,
CONVERT(VARCHAR(10), UpdatedDate, 101) + RIGHT(CONVERT(VARCHAR(32), UpdatedDate, 100), 8) AS UpdatedDate
FROM
m
WHERE
DivID != 0
ORDER BY
CONVERT(VARCHAR(10), UpdatedDate, 101) + RIGHT(CONVERT(VARCHAR(32), UpdatedDate, 100), 8) ASC
The format in the database: smalldatetime 2016-01-25 16:50:00
And to the display value, I use:
CONVERT(VARCHAR(10), UpdatedDate, 101) + RIGHT(CONVERT(VARCHAR(32), UpdatedDate, 100), 8) AS UpdatedDate
My issue: (Hour/Minute Sorting), I need the 7:40PM row at top.
Different order by attempts:
1: Order by UpdatedDate
2: Order by convert(varchar(10),UpdatedDate, 101) desc, right(convert(varchar(32),UpdatedDate,100),8) asc

The problem is you are converting the datetime into Varchar in sort section also..try below query for your output
SELECT DivisionName as Division, StoreNum as Store, LeadName as Lead, Type, ChangeType,Changes,
UpdatedBy,
convert(varchar(10),UpdatedDate, 101) + right(convert(varchar(32), UpdatedDate,100),8) as UpdatedDate FROM m
WHERE DivID!=0
ORDER by UPDATEdDate desc
here in the order clause mentioned only the datetime column so it will sort the rows in desc order of the date and time..
Sql Fiddle

Related

Cannot add STRING_AGG(column, ',') into overall Query

I'm running SQL Server 2017 and my query works perfectly fine, with the exception of when I try to add the following:
,STRING_AGG (TemplateID, ',') as Result1
This is a Stored Procedure supporting an SSRS report in the end.
I need the templateID's to be in a result which would be a comma separated list of values like "1,3,5,12,14,33,44,100,107" (just as an example) Also like to only select Distinct ones if possible.
When I add the above to my overall Stored Procedure, I get the following error in Management Studio:
Msg 8120, Level 16, State 1, Procedure sp_ChangesByUserDetail, Line 11 [Batch Start Line 7]
Column 'ChangeDetail.DisplayName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Here is my entire SELECT statement.
SELECT DisplayName, IsDeleted, TemplateID,TemplateName, Version, Name, UpdatedBy, DataTable, ID, IsVirtual,
DATEADD(minute, DATEDIFF(minute, getutcdate(), GETDATE()), AddedDate) As AddedDate,
CONVERT(varchar(8), DATEADD(minute, DATEDIFF(minute, getutcdate(), GETDATE()), AddedDate), 108)
AS AddedTime, AttachmentContent, UserName, UpdatedDate,
cast(datediff(second, '1970-01-01 00:00:00', AddedDate) as varchar ) + '000' as millisec
,STRING_AGG (TemplateID, ',') as Result1
FROM ChangeDetail WITH (NOLOCK)
where UpdatedBy in (select s from fn_SplitLarge(',',#In_ModifiedBy))
and templatename in (select s from fn_SplitLarge(',',#In_ItemType))
and DATEADD(minute, DATEDIFF(minute, getutcdate(), GETDATE()), AddedDate) between #In_StartDate + #In_StartTime and #In_EndDate + #In_EndTime
Thoughts?
Reason is not having the fields grouped by. Also note that the field for which you group by shouldn't be in the list of fields (and the Name)
ex.
Create table #t (Id int, TemplateName varchar(100))
insert into #t values
(1,'aaa'), (1,'bbb'),(1,'ccc'),(2,'ppp'),(2,'qqq'),(3,'XXX'),(3,'YYY'),(4,'ZZZ ')
SELECT ID, TemplateName FROM #T
-- FOLLOWING DOESN'T WORK
-- SELECT ID, TemplateName, STRING_AGG (TemplateName, ',') as Result1 FROM #T
-- FOLLOWING WORKS
SELECT ID, STRING_AGG (TemplateName, ',') as Result1 FROM #T
GROUP BY ID
So you can make your query as follows:
Select DisplayName, IsDeleted, Version, Name, UpdatedBy, DataTable, ID, IsVirtual,
AddedDate,AddedTime, AttachmentContent, UserName, UpdatedDate, millisec
,STRING_AGG (TemplateID, ',') as Result1
from
(
SELECT DisplayName, IsDeleted, TemplateID,TemplateName, Version, Name, UpdatedBy, DataTable, ID, IsVirtual,
DATEADD(minute, DATEDIFF(minute, getutcdate(), GETDATE()), AddedDate) As AddedDate,
CONVERT(varchar(8), DATEADD(minute, DATEDIFF(minute, getutcdate(), GETDATE()), AddedDate), 108) AS AddedTime,
AttachmentContent, UserName, UpdatedDate,
cast(datediff(second, '1970-01-01 00:00:00', AddedDate) as varchar ) + '000' as millisec
FROM ChangeDetail WITH (NOLOCK)
where UpdatedBy in (select s from fn_SplitLarge(',',#In_ModifiedBy))
and templatename in (select s from fn_SplitLarge(',',#In_ItemType))
and DATEADD(minute, DATEDIFF(minute, getutcdate(), GETDATE()), AddedDate)
between #In_StartDate + #In_StartTime and #In_EndDate + #In_EndTime
) Q
Group By DisplayName, IsDeleted, Version, Name, UpdatedBy, DataTable, ID, IsVirtual,
AddedDate,AddedTime, AttachmentContent, UserName, UpdatedDate, millisec

Filter by input date sql

I have to filter a query result by date using the dd-MM-YY format as input, when I run the query it gives me the empty table, how can I solve?
select Data, string_agg(Ore, ' ') as Ore
from (
select FORMAT(DataCreazione, 'dd/MM/yyyy', 'it-IT') as Data,
CONCAT(DATEPART(HOUR,DataCreazione), ':', DATEPART(MINUTE, DataCreazione)) as
Ore
from Marcatura
where IdUtente = #IdUtente
and (Stato='Ingresso' or Stato='Uscita')
and (CONVERT(datetime, DataCreazione, 103)
between CONVERT(datetime, #Start, 103)
and CONVERT(datetime, #End, 103))
) t
group by Data
order by CONVERT(datetime, Data, 103) desc
​
INPUT VALUE:
#IdUtente=2
#End='14-09-19'
#Start='05-02-19'
Your start and end date are all valid SQL format. You can cast it to datetime, but we need to tell SQL which format is your original date.
cast(CONVERT(VARCHAR(10), CONVERT(date, #Start, 5), 23) as datetime)
complete query:
select Data, string_agg(Ore, ' ') as Ore
from (
select FORMAT(DataCreazione, 'dd/MM/yyyy', 'it-IT') as Data,
CONCAT(DATEPART(HOUR,DataCreazione), ':', DATEPART(MINUTE, DataCreazione)) as
Ore
from Marcatura
where IdUtente = #IdUtente
and (Stato='Ingresso' or Stato='Uscita')
and cast(DataCreazion as DateTime)
between cast(CONVERT(VARCHAR(10), CONVERT(date, #Start, 5), 23) as datetime)
and cast(CONVERT(VARCHAR(10), CONVERT(date, #End, 5), 23) as datetime)
) t
group by Data
order by CONVERT(datetime, Data, 5) desc
Instead you can set connection level property like below.
SET DATEFORMAT DMY;
SELECT Data
,string_agg(Ore, ' ') AS Ore
FROM (
SELECT FORMAT(DataCreazione, 'dd/MM/yyyy', 'it-IT') AS Data
,CONCAT (DATEPART(HOUR, DataCreazione),':',DATEPART(MINUTE, DataCreazione)) AS Ore
FROM Marcatura
WHERE IdUtente = #IdUtente
AND (Stato = 'Ingresso' OR Stato = 'Uscita')
AND (
DataCreazione BETWEEN #Start and #End
)
) t
GROUP BY Data
ORDER BY CONVERT(DATETIME, Data, 103) DESC

Get min and max between two dates

I'm querying the following code, to get min, max and avg, but still give me a problem, because it query all rows that I have from name = 'Jose' and not the min, max, and avg.
SELECT CONVERT(CHAR(10), DATA, 120) AS DATA,
MIN([VALUE]) AS MinValue,
AVG([VALUE]) AS MedValue,
MAX([VALUE]) AS MaxValue
FROM databasename
WHERE (name = 'Jose')
GROUP BY CONVERT(CHAR(10), DATA, 120)
ORDER BY DATA ASC
Example of what I get from the first query:
Image (can't embed image)
To query two dates, I'm using the following code but it don't get any result from query.
SELECT CONVERT(CHAR(10), DATA, 120) AS DATA,
MIN([VALUE]) AS MinValue,
AVG([VALUE]) AS MedValue,
MAX([VALUE]) AS MaxValue
FROM databasename
WHERE [DATA] between '2017-02-01' AND '2018-03-10' AND name = 'Jose'
GROUP BY CONVERT(CHAR(10), DATA, 120)
ORDER BY DATA ASC
I'm using MSSQL database.
UPDATE:
I already can query between two dates, as you can see in the second query. Problem that I'm not getting only min, max and avg.
Image:
try this SQL Query Convert(DATE,'2017-02-01').
SELECT DATA AS DATA,
MIN([VALUE]) AS MinValue,
AVG([VALUE]) AS MedValue,
MAX([VALUE]) AS MaxValue
FROM databasename
WHERE [DATA] between CONVERT(DATE, '2017-02-01') AND CONVERT(DATE, '2018-03-10')
AND name = 'Jose'
GROUP BY CONVERT(DATE, '2017-02-20')
ORDER BY CONVERT(DATE, '2017-02-20') ASC
can you consider small change in your query
SELECT CONVERT(CHAR(10), DATA, 120) AS DATA,
MIN([VALUE]) AS MinValue,
AVG([VALUE]) AS MedValue,
MAX([VALUE]) AS MaxValue
FROM databasename
WHERE CONVERT(CHAR(10), DATA, 120) between CONVERT(CHAR(10), 2017 - 02 - 20, 120) AND
CONVERT(CHAR(10), 2018 - 02 - 25, 120) AND name = 'Jose'
GROUP BY CONVERT(CHAR(10), DATA, 120)
ORDER BY DATA ASC

Date filter on view output (dd/mm/yyy) SQL Server

I am taking output from a view that has a column CreatedDate which is returned in a dd/mm/yyyy format. I want to filter output on behalf of date but nothing is showing up. Can anybody help me?
SQL Server code:
;with CTE as
(
select
CreatedDate,
UserID,
UserName,
SUM([CreditedAmount]) as CreditedAmount,
SUM([TDSPercent]) as TDSPercent,
SUM([TDSAmount]) as TDSAmount,
SUM(ISNULL([ApplicationServicePercentage], 0)) as ApplicationServicePercentage,
SUM(ISNULL([ApplicationServiceAmount], 0)) as ApplicationServiceAmount,
SUM([CreditedAmount]) - SUM([DebitedAmount]) - SUM(ISNULL([TDSAmount], 0)) - SUM(ISNULL([ApplicationServiceAmount], 0)) as AmountToPay
from
[dbo].[vwGetPaymentStatement]
where
[Status] = 0
and UserStatus = 1
group by
UserID, UserName, CreatedDate
)
select
CreatedDate,
UserID, UserName,
CreditedAmount, TDSPercent, TDSAmount,
ApplicationServicePercentage,
ApplicationServiceAmount,
AmountToPay
from
CTE
where
AmountToPay is not null
and (UserID = #uid or UserName like '%' + #username + '%')
and (CreatedDate between #datefrom and #dateto)
Try casting to date if its not working?
(cast(CreatedDate as datetime) between #datefrom and dateto)
You hopefully already have your variables declared as datetime and dont need to cast those.
Based on your comments, and responses to other answers, I know that:
Your CreatedDate field is a VARCHAR
Your CreatedDate field has data which aren't proper dates.
I would start by running the definition of the CTE with one addition to help find the non-date values, which is as follows:
select
CreatedDate,
UserID,
UserName,
SUM([CreditedAmount]) as CreditedAmount,
SUM([TDSPercent]) as TDSPercent,
SUM([TDSAmount]) as TDSAmount,
SUM(ISNULL([ApplicationServicePercentage], 0)) as ApplicationServicePercentage,
SUM(ISNULL([ApplicationServiceAmount], 0)) as ApplicationServiceAmount,
SUM([CreditedAmount]) - SUM([DebitedAmount]) - SUM(ISNULL([TDSAmount], 0)) - SUM(ISNULL([ApplicationServiceAmount], 0)) as AmountToPay
from
[dbo].[vwGetPaymentStatement]
where
[Status] = 0
and UserStatus = 1
and isdate(createddate) = 0 --- > Added this row to find the non-date values
group by
UserID, UserName, CreatedDate
Once you figure out what to do with those non-date values you should be fine. Unless you have an issue with the data types of the #datefrom and #dateto variables.
SELECT createddate,
userid,
username,
creditedamount,
tdspercent,
tdsamount,
applicationservicepercentage,
applicationserviceamount,
amounttopay
FROM cte
WHERE amounttopay IS NOT NULL
AND ( userid = #uid
OR username LIKE '%' + #username + '%' )
AND ( createddate BETWEEN CONVERT(VARCHAR, Cast(#datefrom AS DATETIME),
103) AND
CONVERT(VARCHAR, Cast(#dateto AS DATETIME
), 103)

SQL Server: select distinct mon-yyyy format output sorty by descending order

I have datetime column in a table with following data:
2011-03-23
2011-04-19
2011-04-26
2011-05-26
I want to select distinct mon-yyyy format output ordered by report date descending. We need to select only one column in the SQL statement
This SQL works, but I want to order by ReportDate column
SELECT distinct SUBSTRING (convert(varchar, ReportDate, 100),1,3) +'-'+
SUBSTRING (convert(varchar, ReportDate, 100),8,4 )
FROM [EnvelopsDB].[dbo].[Envelopes]
output
Apr-2011
Mar-2011
May-2011
This SQL gives an error:
SELECT distinct SUBSTRING (convert(varchar, ReportDate, 100),1,3) +'-'+
SUBSTRING (convert(varchar, ReportDate, 100),8,4 )
FROM [EnvelopsDB].[dbo].[Envelopes]
order by ReportDate
Error:
Msg 145, Level 15, State 1, Line 2
ORDER BY items must appear in the select list if SELECT DISTINCT is
specified.
What is the best SQL query to get the output I need?
with testdata as
(
select cast('2011-03-23' as datetime) as d
union all
select cast('2011-04-19' as datetime)
union all
select cast('2011-04-26' as datetime)
union all
select cast('2011-05-26' as datetime)
)
SELECT DATENAME(month,d)+'-'+DATENAME(year,d)
FROM testdata
GROUP BY DATEPART(year,d), DATEPART(month,d), DATENAME(month,d),DATENAME(year,d)
ORDER BY DATEPART(year,d), DATEPART(month,d)
SELECT DATENAME(month,ReportDate)+'-'+DATENAME(year,ReportDate)
FROM [EnvelopsDB].[dbo].[Envelopes]
GROUP BY DATEPART(year,ReportDate), DATEPART(month,ReportDate), DATENAME(month,ReportDate),DATENAME(year,ReportDate)
ORDER BY DATEPART(year,ReportDate), DATEPART(month,ReportDate)
You can use GROUP BY instead of DISTINCT like this
SELECT SUBSTRING (convert(varchar, ReportDate, 100),1,3) +'-'+
SUBSTRING (convert(varchar, ReportDate, 100),8,4 )
FROM [EnvelopsDB].[dbo].[Envelopes]
GROUP BY SUBSTRING (convert(varchar, ReportDate, 100),1,3) +'-'+
SUBSTRING (convert(varchar, ReportDate, 100),8,4 )
With order by on ReportDate desc, using row_number() instead of group by.
select substring(convert(varchar, Env.ReportDate, 100),1,3) +'-'+
substring(convert(varchar, Env.ReportDate, 100),8,4 )
from (select
ReportDate,
row_number() over(partition by datepart(year, ReportDate), datepart(month, ReportDate)
order by (select 1)) as rn
from [EnvelopsDB].[dbo].[Envelopes]) as Env
where Env.rn = 1
order by Env.ReportDate desc
I think there was a similar question here recently, which I can't find now, but the answer was something to this effect:
SELECT
SUBSTRING(CONVERT(varchar, ReportDate, 100), 1, 3) + '-' +
SUBSTRING(CONVERT(varchar, ReportDate, 100), 8, 4)
FROM [EnvelopsDB].[dbo].[Envelopes]
GROUP BY
SUBSTRING(CONVERT(varchar, ReportDate, 100), 1, 3),
SUBSTRING(CONVERT(varchar, ReportDate, 100), 8, 4)
ORDER BY MIN(ReportDate)
Also, while the way you've chosen to present the output in the format of mmm-yyyy is basically fine, I would probably do the same slightly differently. Here:
SELECT
LEFT(DATENAME(month, ReportDate), 3) + '-' +
DATENAME(year, ReportDate)
FROM [EnvelopsDB].[dbo].[Envelopes]
GROUP BY
DATENAME(month, ReportDate),
DATENAME(year, ReportDate)
ORDER BY MIN(ReportDate)
If you do not mind an extra column in the result set, then this will work.
SELECT DISTINCT
REPLACE(RIGHT(CONVERT(VARCHAR(11), ReportDate, 106), 8), ' ', '-') AS [Mon-YYYY],
RANK() OVER(ORDER BY CONVERT(VARCHAR(7), ReportDate, 120) /* [YYYY-MM]*/ DESC) AS r_order
FROM [EnvelopsDB].[dbo].[Envelopes]
ORDER BY r_order DESC
If you don't want to provide a column alias for the MMM-YYYY (which you can then use in the ORDER BY), can't you just do **ORDER BY 1 DESC**?
SELECT DISTINCT
SUBSTRING (convert(varchar, ReportDate, 100),1,3) +'-'+
SUBSTRING (convert(varchar, ReportDate, 100),8,4 )
FROM [EnvelopsDB].[dbo].[Envelopes]
ORDER BY 1 DESC
Or just add a column alias:
SELECT DISTINCT
SUBSTRING (convert(varchar, ReportDate, 100),1,3) +'-'+
SUBSTRING (convert(varchar, ReportDate, 100),8,4 ) AS ReportDate
FROM [EnvelopsDB].[dbo].[Envelopes]
ORDER BY ReportDate DESC