Sql where Condition execution not working - sql

I have the following query logic
Show comments which is not deleted
Show comments which is deleted after created, within a timespan of 30 days before today(Today - Createddate <= 30)
Below is the logic which I wrote, but I don't think it is working correct.
SELECT string_agg(
CAST(CONCAT_WS(',',
c.Id,
COALESCE(c.ParentCommentId, 0),
c.TotalRatingsCount,
c.Pinned,
c.IsDeleted,
FORMAT(c.CreatedDate, 'yyyy-MM-dd HH:mm:ss')) AS VARCHAR(MAX))
, '|')
FROM Comments c
WHERE c.DiscussionId = d.Id
and
((c.IsDeleted = 0 and DATEDIFF(day, c.CreatedDate , GETDATE()) >= 30))
or
(((c.IsDeleted = 1 or c.IsDeleted =0) and DATEDIFF(day, c.CreatedDate , GETDATE()) <= 30))

SELECT string_agg(
CAST(CONCAT_WS(',',
c.Id,
COALESCE(c.ParentCommentId, 0),
c.TotalRatingsCount,
c.Pinned,
c.IsDeleted,
FORMAT(c.CreatedDate, 'yyyy-MM-dd HH:mm:ss')) AS VARCHAR(MAX))
, '|')
FROM Comments c
WHERE c.DiscussionId = d.Id
and
((c.IsDeleted = 0 )
or
((c.IsDeleted = 1 ) and DATEDIFF(day, c.CreatedDate , GETDATE()) <= 30))

Related

Sub query Count SQL

I have this code I need to have row count off. I tried to count it but comes as Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
Can you help me with row count, thank you.
select count((
select a.GIRIS_ZAMANI, a.CIKIS_ZAMANI, a.PLAKA, a.UCRET, b.KAMERA_ADI
from ARAC_CIKIS a
left join KAMERALAR b
on b.KAMERA_ID = a.CIKIS_KAMERA_ID
where a.CIKIS_ZAMANI between
(select cast(cast(sysutcdatetime() as date) as datetime) + cast('00:00:00' as datetime)) and
(select cast(cast(sysutcdatetime() as date) as datetime) + cast('23:59:59' as datetime)) and
a.UCRET>0
)
)
You can try below -
select count(*)
from
(
select a.GIRIS_ZAMANI, a.CIKIS_ZAMANI, a.PLAKA, a.UCRET, b.KAMERA_ADI from ARAC_CIKIS a left join KAMERALAR b on b.KAMERA_ID = a.CIKIS_KAMERA_ID
where a.CIKIS_ZAMANI between cast(cast(sysutcdatetime() as date) as datetime)
+ cast('00:00:00' as datetime) and cast(cast(sysutcdatetime() as date) as datetime)
+ cast('23:59:59' as datetime)
and a.UCRET>0
) A
Why are you using a subquery?
select count(*)
from ARAC_CIKIS a left join
KAMERALAR k
on bkKAMERA_ID = a.CIKIS_KAMERA_ID
where a.CIKIS_ZAMANI between cast(cast(sysutcdatetime() as date) as datetime) + cast('00:00:00' as datetime) and
cast(cast(sysutcdatetime() as date) as datetime) + cast('23:59:59' as datetime) and
a.UCRET > 0

Conversion of string to DateTime & using conversion in Where Clause - DateDiff

I have a string column that contains dates. I want to convert string to date so that i can use the Date Logic ahead.
I have converted the string to DateTime but while applying the logic in the Where clause it doesn't allow me to use the Column.
SELECT a.code,
CONVERT(DATETIME,b.[FieldValue],103) as [Date1]
FROM [dbo].employeedetail as A join [dbo].CustomeFieldDetail as B
on A.Id = B.EMployeeid
WHERE a.empstatus = 1
AND B.CustomeFieldName = 'PASSPORT' AND
( Datediff(dd, Getdate(), Dateadd(yyyy, Datediff(yyyy, b.[Date1],
Getdate())
+
1, b.[Date1]))
+ 1 ) % 366 = 50
Can anyone help me?
Use APPLY to introduce a reusable expression.
SELECT a.code,
c.[Date1]
FROM [dbo].employeedetail as A
JOIN [dbo].CustomeFieldDetail as B ON A.Id = B.EMployeeid
CROSS APPLY (
SELECT CONVERT(DATETIME,b.[FieldValue],103) as [Date1]
) c
WHERE a.empstatus = 1
AND B.CustomeFieldName = 'PASSPORT' AND
( Datediff(dd, Getdate(), Dateadd(yyyy, Datediff(yyyy, c.[Date1],
Getdate())
+
1, c.[Date1]))
+ 1 ) % 366 = 50
A better solution is store dates as DATE, DATETIME, not strings.
Using CTE results in an even more compact query:
WITH B AS (
SELECT *, CONVERT(DATETIME, [FieldValue], 103) AS [Date1]
FROM [dbo].CustomeFieldDetail
WHERE (CustomeFieldName = 'PASSPORT')
)
SELECT A.code, B.[Date1]
FROM [dbo].EmployeeDetail AS A JOIN B ON A.Id = B.EMployeeid
WHERE (A.empstatus = 1)
AND (((DATEDIFF(dd, GETDATE(),
DATEADD(yyyy, DATEDIFF(yyyy, B.[Date1], GETDATE()) + 1, B.[Date1])) + 1)
% 366) = 50)

SQL Server 2014 Select total for each day

Hello I am working on a dataset for a report in SSRS
and I have a query which gives the total requests in the backlog :
SELECT
COUNT(*) as NB
FROM p_rqt WITH (NOLOCK)
INNER JOIN p_cpy WITH (NOLOCK) ON p_cpy.CpyInCde = p_rqt.OrigCpyInCde
WHERE
CpyTypInCde IN (27, 31)
AND p_rqt.RqtNatInCde IN (74, 75, 76)
AND HeadRqtInCde = 0
AND p_rqt.OrigCpyInCde LIKE CASE WHEN #Client = 0 THEN '%' ELSE #Client END
AND ((RcvDte < DATEADD(day, 1, #DateDeb) AND RqtEndDte IS NULL) OR
(RcvDte < DATEADD(day, 1, #DateDeb) AND RqtEndDte > DATEADD(day, 1, #DateDeb)))
and I want to retrieve the total amount left per day.
I tried lot of things like this :
SELECT CONVERT(date,rcvdte,103), count(*) as nb
FROM p_rqt p WITH (NOLOCK)
INNER JOIN p_cpy WITH (NOLOCK) ON p_cpy.CpyInCde = p.OrigCpyInCde
WHERE
CpyTypInCde IN (27, 31)
AND p.RqtNatInCde IN (74, 75, 76)
AND HeadRqtInCde = 0
AND ((RcvDte < DATEADD(day, 1, '20170901') AND RqtEndDte IS NULL) OR (RcvDte < DATEADD(day, 1, '20170901') AND RqtEndDte > DATEADD(day, 1, '20170901')))
group by CONVERT(date,rcvdte,103)
order by CONVERT(date,rcvdte,103)
I tried inner join subqueries, Sum and other stuff
but all I can manage to do is to have the number of records added per day
and I want something like this :
date: NB:
01/01/2017 1950
02/01/2017 1954 (+4 items)
03/01/2017 1945 (-9 items)
Thank you
Use LAG:
WITH cte AS (
SELECT
CONVERT(date, rcvdte, 103) AS date,
COUNT(*) AS nb
FROM p_rqt p WITH (NOLOCK)
INNER JOIN p_cpy WITH (NOLOCK)
ON p_cpy.CpyInCde = p.OrigCpyInCde
WHERE
CpyTypInCde IN (27, 31) AND
p.RqtNatInCde IN (74, 75, 76) AND
HeadRqtInCde = 0 AND
((RcvDte < DATEADD(day, 1, '20170901') AND RqtEndDte IS NULL) OR (RcvDte < DATEADD(day, 1, '20170901') AND RqtEndDte > DATEADD(day, 1, '20170901')))
GROUP BY CONVERT(date, rcvdte, 103)
ORDER BY CONVERT(date, rcvdte, 103)
)
SELECT
t1.date,
(SELECT SUM(t2.nb) FROM cte t2 WHERE t2.date <= t1.date) AS nb,
CASE WHEN t1.nb - LAG(t1.nb, 1, t1.nb) OVER (ORDER BY t1.date) > 0
THEN '(+' + (t1.nb - LAG(t1.nb, 1, t1.nb) OVER (ORDER BY t1.date)) + ' items)'
ELSE '(' + (t1.nb - LAG(t1.nb, 1, t1.nb) OVER (ORDER BY t1.date)) + ' items)'
END AS difference
FROM cte t1
ORDER BY t1.date;
So i found a solution but it is really slow,
i still post the answer anyway
DECLARE #Tb TABLE ( Colonne1 Datetime, Colonne2 INT )
DECLARE #Debut Datetime = '01/09/2017'
WHILE #Debut < '13/09/2017'
BEGIN
DECLARE #Compteur int = (
SELECT
COUNT(1) NB
FROM p_rqt WITH (NOLOCK)
INNER JOIN p_cpy WITH (NOLOCK) ON p_cpy.CpyInCde = p_rqt.OrigCpyInCde
WHERE
CpyTypInCde IN (27, 31)
AND p_rqt.RqtNatInCde IN (74, 75, 76)
AND HeadRqtInCde = 0
AND p_rqt.OrigCpyInCde LIKE '%'
AND (
(RcvDte < #Debut AND RqtEndDte IS NULL)
OR
(RcvDte < #Debut AND RqtEndDte > #Debut)
)
)
INSERT INTO #Tb (Colonne1, Colonne2) VALUES (#Debut, #Compteur)
SET #Debut = DATEADD(day, 1, #Debut)
IF #Debut > '13/09/2017'
BREAK
ELSE
CONTINUE
END
SELECT * FROM #Tb

Calculate Days Present and absent from the table

I have a table name Emp_mon_day which consists Employees Present and Absent details.
What I want is
I need for these 9 employees, information about days present and days absent for each employees from Emp_mon_day table merged in to below query
QUERY
SELECT e.comp_mkey,
e.status,
e.resig_date,
dt_of_leave,
e.emp_name,
e.date_of_joining,
e.emp_card_no,
a.pl_days,
pl_days_opening,
a.month1,
a.month2,
a.month3,
a.month4,
a.month5,
a.month6,
a.month7,
a.month8,
a.month9,
a.month10,
a.month11,
a.month12,
a.month1 + a.month2 + a.month3 + a.month4 + a.month5 + a.month6 + a.month7 + a.month8 + a.month9 + +a.month10 + a.month11 + a.month12 AS pl_sum
FROM p_leave_allocation AS a
INNER JOIN
emp_mst AS e
ON a.emp_card_no = e.emp_card_no
WHERE a.year = 2016
AND (datediff(MONTH, e.date_of_joining, CONVERT (DATETIME, getdate(), 103)) >= 6
AND datediff(MONTH, e.date_of_joining, CONVERT (DATETIME, getdate(), 103)) <= 36)
AND (e.resig_date IS NULL
OR (e.dt_of_leave IS NOT NULL
AND e.dt_of_leave >= CONVERT (DATETIME, getdate(), 103)))
AND e.status IN ('A', 'S')
AND e.comp_mkey IN (7, 110)
AND a.Year = 2016;
The above query gives me data as below
[![Image data][1]][1]
Column details for Emp_mon_day is below
[![enter image description here][2]][2]
You can try the below query:
SELECT e.comp_mkey, e.status, e.resig_date, dt_of_leave, e.emp_name,
e.date_of_joining, e.emp_card_no, a.pl_days, pl_days_opening, a.month1,
a.month2, a.month3, a.month4, a.month5, a.month6, a.month7, a.month8,
a.month9, a.month10, a.month11, a.month12,
a.month1 + a.month2 + a.month3 + a.month4 + a.month5 + a.month6 + a.month7 + a.month8 + a.month9 + +a.month10 + a.month11 + a.month12 AS pl_sum,
m.[DaysAbsent],m.[DaysPresent]
FROM p_leave_allocation AS a
INNER JOIN
emp_mst AS e
ON a.emp_card_no = e.emp_card_no
INNER JOIN
(
SELECT
comp_mkey,emp_mkey,[month],[year],
SUM(CASE WHEN data ='AB' THEN 1 ELSE 0 END) AS [DaysAbsent],
SUM(CASE WHEN data ='P' THEN 1 ELSE 0 END) AS [DaysPresent]
FROM
(
SELECT comp_mkey,emp_mkey,[month],[year],[Day1],[Day2],[Day3],[Day4],[Day5]
--,...
FROM Emp_mon_day
) source
UNPIVOT
(
data FOR day IN ([Day1],[Day2],[Day3],[Day4],[Day5]) -- dynamic query can generate all days data
)up
GROUP BY comp_mkey, emp_mkey,[month],[year]
) AS m
ON m.comp_mkey=e.Comp_mkey and m.emp_mkey=e.mkey
--- ABOVE CRITERIA NEEDS TO BE CHECKED
WHERE a.year = 2016
AND (datediff(MONTH, e.date_of_joining, CONVERT (DATETIME, getdate(), 103)) >= 6
AND datediff(MONTH, e.date_of_joining, CONVERT (DATETIME, getdate(), 103)) <= 36)
AND (e.resig_date IS NULL
OR (e.dt_of_leave IS NOT NULL
AND e.dt_of_leave >= CONVERT (DATETIME, getdate(), 103)))
AND e.status IN ('A', 'S')
AND e.comp_mkey IN (7, 110)
AND a.Year = 2016;
Explanation:
We've added another INNER JOIN to the existing query to get collated data of DaysPresent and DaysAbsent
To optimize this further, I'd suggest you directly apply following WHERE clause to source set
WHERE comp_mkey IN (7, 110) AND Year = 2016;

How to display event hour by hour in SQL?

Create table tblEvent ( Event_ID int, Start_Time datetime, End_Time datetime )
insert into tblEvent values(1,'2015-02-10 9:00:00.000','2015-02-10 11:00:00.000')
insert into tblEvent values(2,'2015-02-10 11:00:00.000','2015-02-10 11:20:00.000')
insert into tblEvent values(3,'2015-02-10 11:20:00.000','2015-02-10 13:00:00.000')
and want to be display like below
Hour Event_ID [Start_End]
9 1 9:00-10:00
10 1 10:00-11:00
11 2 11:00-11:20
11 3 11:20-12:00
12 3 12:00-13:00
and we can make the End_Time of Event 3 become 13:30
we had to be display
13 3 13:00-13:30
Can anyone help me?
You can use DATEPART function
DATEPART(HOUR, [Start_End]) AS Hour
select blocks.Hour, e.Event_Id,
format(case when e.Start_Time > blocks.Start_Time then e.Start_Time else blocks.Start_Time end, 'HH:mm') +
'-' +
format(case when e.End_Time < blocks.End_Time then e.End_Time else blocks.End_Time end, 'HH:mm')
from
tblEvent as e inner join
(
select
d0.n + d1.n * 4 as Hour,
dateadd(hh, d0.n + d1.n * 4, cast(cast(current_timestamp as date) as datetime)) as Start_Time,
dateadd(hh, d0.n + d1.n * 4 + 1, cast(cast(current_timestamp as date) as datetime)) as End_Time
from
(select 0 as n union all select 1 union all select 2 union all select 3) as d0,
(select 0 as n union all select 1 union all select 2 union all select 3 union all select 4 union all select 5) as d1
) as blocks
on blocks.End_Time > e.Start_Time and blocks.Start_Time < e.End_Time
order by Event_Id, Hour
Here's a start. SQL Server? Is current day enough? You don't have the format() on SQL 2008 so you'll have to do that part yourself.
I'm not sure this handles all the cases exactly the way you want. You can take the basic idea and extend it across a longer range of hours, say 168 for a full week.
http://sqlfiddle.com/#!6/819c0/9
TRY Some thing like this.This sample data is running ok.
Please provide another sample data atleast 10 rows and don't forget to paste desired output.
Also read my comment in script.
DECLARE #tblEvent TABLE (
Event_ID INT
,Start_Time DATETIME
,End_Time DATETIME
)
INSERT INTO #tblEvent
VALUES (
1
,'2015-02-10 9:00:00.000'
,'2015-02-10 11:00:00.000'
)
,(
2
,'2015-02-10 11:00:00.000'
,'2015-02-10 11:20:00.000'
)
,(
3
,'2015-02-10 11:20:00.000'
,'2015-02-10 13:00:00.000'
);
--select *,DATEdiff(hour,a.Start_Time,a.End_Time) from #tblEvent a
;
WITH CTE
AS (
SELECT *
,ROW_NUMBER() OVER (
ORDER BY Start_Time
) RN
,DATEdiff(hour, Start_Time, End_Time) Diff
FROM #tblEvent
)
--select * from cte
,CTE1
AS (
SELECT Event_ID
,Start_Time
,CASE
WHEN Diff > 1
THEN DATEADD(minute, 60 - DATEPART(minute, Start_Time), Start_Time)
ELSE End_Time
END End_Time
,RN
,DIFF
,1 RN1
,DATEPART(minute, Start_Time) DIFFMIN
FROM CTE
--WHERE RN = 1
UNION ALL
SELECT CASE
WHEN A.Diff > B.DIFF
THEN b.Event_ID
ELSE a.Event_ID
END
,B.End_Time Start_Time
,CASE
WHEN A.Diff > B.DIFF
THEN DATEADD(minute, 60 - DATEPART(minute, B.Start_Time), B.End_Time)
ELSE A.End_Time
END End_Time
,CASE
WHEN A.Diff > B.DIFF
THEN B.RN
ELSE B.RN + 1
END RN
,CASE
WHEN A.Diff > B.DIFF
THEN B.DIFF - 1
ELSE A.Diff
END
,RN1 + 1
,0
FROM CTE1 B
CROSS APPLY (
SELECT *
FROM CTE
WHERE RN = B.RN
) A
WHERE B.DIFF > 0
)
SELECT [Hour]
,Event_ID
,[Start_End]
FROM (
SELECT DATEPART(HOUR, Start_Time) [Hour]
,ROW_NUMBER() OVER (
PARTITION BY Start_Time ORDER BY Start_Time
) RN2
,Event_ID
,CONVERT(VARCHAR(5), Start_Time, 114) + '-' + CONVERT(VARCHAR(5), End_Time, 114) [Start_End]
FROM CTE1
) TBL
WHERE RN2 = 1
--BELOW QUERY RETURN 6 ROWS
-- I AM TRYING TO ELIMINATE THE EXTRA ROWS WITHOUT ROW_NUMBER
--WHICH WOULD BE MORE OPTIMIZE,BUT I AM NOT GETTING WHAT ACTUALLY CAUSING THIS BEHAVIOUR
--MEANWHILE YOU CAN TEST OTHER SAMPLE DATA,AND THROW OTHER SAMPLE DATA
--SELECT DATEPART(HOUR, Start_Time) [Hour]
-- ,Event_ID
-- ,CONVERT(VARCHAR(5), Start_Time, 114) + '-' + CONVERT(VARCHAR(5), End_Time, 114) [Start_End]
-- FROM CTE1