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

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

Related

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 Sorting Date With Hours/Mins

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

SQL Server : datetime incorrect results

Using SQL Server 2008,
I have a procedure as follows:
SELECT
UserId, Name, Company, LanguageId, CodeRegisteredWith, TotalLoggedInDuration,
Region, IsAdmin,
IsRep, IsRetailer, IsTeamLeader, [dateregistered]
FROM
RoundupAcademy.dbo.UserProfile WITH(NOLOCK)
WHERE
(Convert(smalldatetime, DateRegistered, 120) >= Convert(smalldatetime, '2013-1-1', 120)
AND (Convert(smalldatetime, DateRegistered, 120) <= convert(smalldatetime, '2013-8-8', 120)))
This works fine and shows the results between the dates.
However when expanding on this query and some more conditions as follows:
SELECT
UserId, Name, Company, LanguageId, CodeRegisteredWith, TotalLoggedInDuration,
Region, IsAdmin, IsRep, IsRetailer, IsTeamLeader, [dateregistered]
FROM
RoundupAcademy.dbo.UserProfile WITH(NOLOCK)
WHERE
UserId is not null OR UserId not like ''
AND
(#LanguageID = 0 OR ([LanguageID] = #LanguageID ))
AND
((Convert(smalldatetime, DateRegistered, 120) >= Convert(smalldatetime, #datereg, 120)
AND (Convert(smalldatetime, DateRegistered, 120) <= convert(smalldatetime, #dateend, 120))))
it seems any date shows.
not sure what the problem is as my other conditions look fine.
any ideas?
Replace
WHERE UserId is not null OR UserId not like ''
with
WHERE (UserId is not null OR UserId not like '')
Otherwise you would get all records where UserId is not null or the other conditions are true.
query should be like these
SELECT UserId, Name, Company, LanguageId, CodeRegisteredWith, TotalLoggedInDuration, Region, IsAdmin,
IsRep, IsRetailer, IsTeamLeader, [dateregistered] FROM RoundupAcademy.dbo.UserProfile WITH(NOLOCK)
WHERE( UserId is not null OR UserId not like '')
AND
(#LanguageID = 0 OR ([LanguageID] = #LanguageID ))
AND
((Convert(smalldatetime,DateRegistered, 120) >= Convert(smalldatetime,#datereg, 120)
AND (Convert(smalldatetime,DateRegistered, 120) <= convert(smalldatetime,#dateend, 120))))