Subqueries with update statement in sql - sql

I have the following query:
SELECT
CONVERT(datetime, CONVERT(varchar, new_time, 101)) As day,
datepart(hh,new_time) As hour,count(*) As Total
FROM
log_table
WHERE
new_time > GETDATE() - 180
GROUP BY
CONVERT(datetime, CONVERT(varchar, new_time, 101)),datepart(dd,new_time), datepart(hh,new_time)
ORDER BY
CONVERT(datetime, CONVERT(varchar, new_time, 101)), datepart(hh,new_time));
I need to update the table 'tmp_table' based on its results. I tried the following, but it's not working:
UPDATE tmp_table
SET count=Total
WHERE date=day AND hour=hour
FROM
(
select CONVERT(datetime, CONVERT(varchar, new_time, 101)) As day,
datepart(hh,new_time) As hour,count(*) As Total
from log_table
where new_time > GETDATE() - 180
group by CONVERT(datetime, CONVERT(varchar, new_time, 101)),datepart(dd,new_time),
datepart(hh,new_time)
order by CONVERT(datetime, CONVERT(varchar, new_time, 101)), datepart(hh,new_time))
)
I need to get the values "Total", "day" and "hour" from the subquery.

If you only want to update, then you don't need to order by and therefore you can use a CTE and a join as such:
With CTE AS
(
SELECT CONVERT(DATETIME, CONVERT(VARCHAR, new_time, 101)) As day,
DATEPART(hh,new_time) As hour,
COUNT(*) As Total
FROM log_table
WHERE new_time > GETDATE() - 180
GROUP BY CONVERT(DATETIME, CONVERT(VARCHAR, new_time, 101)),
DATEPART(dd,new_time),
DATEPART(hh,new_time)
)
UPDATE tmp_table
SET Count= CTE.Total
FROM tmp_table INNER JOIN CTE
ON temp_table.date=cte.day AND temp_table.hour=cte.hour

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

How to convert sql dates range to Daily Row

How do I convert a date range so each day is 1 row with the start and end time for that day?
I looked at this post about date ranges to row - but this is a different problem. The other solution linked above does not give the time from start to finish for each day - and thus does not allow for duty factor or utilization calculations, and or the build of a Gantt chart.
We would have an ID field, a Start Date, and an End Date as our base table. We want to convert this to contain the ID Field per day with how much time was consumed in that range.
This is very useful when converting a start and end dates to daily duty factor and a host of other needs like equipment utilization.
I had a lot of help from this community figuring this out. I wanted to put the final SQL script here for others to use as well.
WITH cte ([VID],[StartTime],[EndTime]) AS
( SELECT tbl.[ID] as 'VID'
,CONVERT(VARCHAR(19), tbl.[StartDT], 120) AS 'StartTime'
,CASE
WHEN tbl.[EndDT] <= CONVERT(VARCHAR(11), tbl.[StartDT]+1, 120) + '00:00:00' THEN CONVERT(VARCHAR(19), tbl.[EndDT], 120)
ELSE CONVERT(VARCHAR(11), tbl.[StartDT]+1, 120) + '00:00:00'
END as 'EndTime'
FROM [SourceTable] as tbl
WHERE DATEDIFF(DAY,tbl.[StartDT],tbl.[EndDT] )<=365
UNION ALL
SELECT tbl.[ID] as 'VID'
,CONVERT(VARCHAR(11), DATEADD(DAY, 1, cte.[StartTime]), 120) + '00:00:00' AS 'StartTime'
,CASE
WHEN CONVERT(VARCHAR(19), tbl.[EndDT], 120) < CONVERT(VARCHAR(11), DATEADD(DAY, 2, cte.[StartTime]), 120) + '00:00:00'
THEN CONVERT(VARCHAR(19), tbl.[EndDT], 120)
ELSE CONVERT(VARCHAR(11), DATEADD(DAY, 2, cte.[StartTime]), 120) + '00:00:00'
END AS 'EndTime'
FROM cte
INNER JOIN [SourceTable] as tbl
ON cte.VID = tbl.ID
WHERE CONVERT(VARCHAR(11), cte.[StartTime], 120) < CONVERT(VARCHAR(11), tbl.[EndDT], 120))
SELECT VID AS ID
,[StartTime]
,[EndTime]
,DateDiff (second,[StartTime],[EndTime]) / 3600 As 'Hours'
,DateDiff (second,[StartTime],[EndTime])/60 % 60 as 'Minutes'
,((DateDiff (Second,[StartTime],[EndTime]) / 3600)*60)+(DateDiff (second,starttime,endtime)/60 % 60) as 'Total Minutes'
,DATEPART(week,[StartTime]) AS weeknum
,MONTH([StartTime]) AS MonthNumber
,DATENAME(month,[StartTime]) AS MonthName
FROM cte order by Id, [StartTime]
option (maxrecursion 0);

mssql 2012 how display specific value

i have query
SELECT DATEDIFF(day,
CONVERT(char(10), GetDate(),101),
CONVERT(char(10), fieldname,101))
from tablename
where isdate(fieldname)=1
the output of query is
how i can display only value like 6 from the result???
SELECT DATEDIFF(day, CONVERT(char(10), GetDate(),101), CONVERT(char(10), fieldname,101))
FROM lablename
WHERE isdate(fieldname)=1
AND DATEDIFF(day, CONVERT(char(10), GetDate(),101), CONVERT(char(10), fieldname,101)) = 6
edit 1
SELECT * FROM
( SELECT DATEDIFF(day, CONVERT(char(10), GetDate(),101), CONVERT(char(10), fieldname,101)) AS DateDiff
FROM lablename
WHERE isdate(fieldname)=1
) A
WHERE DateDiff = 6

How do I group DATE field by YEAR-MM in SQL Server?

I have a date field in a query and I do want to get GROUP BY report like this:
DATE COUNT
2010-01 10
2010-02 2
...
2010-12 24
2012-13 34
What is the proper syntax to obtain this on SQL Server?
All these conversions to string work, but I find this method more efficient, albeit less readable:
SELECT m = DATEADD(MONTH, DATEDIFF(MONTH, 0, [DATE]), 0), COUNT(*)
FROM dbo.TheTable
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, [DATE]), 0);
If you don't want to repeat the expression, then:
;WITH x AS (SELECT m = DATEADD(MONTH, DATEDIFF(MONTH, 0, [DATE]), 0)
FROM dbo.TheTable)
SELECT m, COUNT(*)
FROM x GROUP BY m;
This way the output is still a date/time value and can be used that way for other things. And it doesn't involve any messy string conversions.
CONVERT(VARCHAR(7), CreationDate, 120) as Date
You can simply do:
select convert(char(7), #myDate, 20)
Example
declare #myDate as DateTime
set #myDate = '2012-06-23'
select convert(char(7), #myDate, 20)
Output
-------
2012-06
So the full statement would look like:
select convert(char(7), myDate, 20), count(*) as Count
from MyTable
group by convert(char(7), myDate, 20)
Update
The sample data includes the value 2012-13. I am going to assume this is a typo and that the number after the dash represents the month.
SELECT CAST(DATEPART(year, dateCol) as VARCHAR) + '-' + CAST(DATEPART(month, dateCol) as VARCHAR) as Date, count(*) As Count
FROM myTable
GROUP BY CAST(DATEPART(year, dateCol) as VARCHAR) + '-' + CAST(DATEPART(month, dateCol) as VARCHAR)

nested select statement with SUM

I would like to know if its possible to write a nested select statment?
I have the following which calculates the booked time:
SELECT description, SUM(ts.booked_time) AS booked_time_total,
CONVERT(VARCHAR(11), #testDate, 106) AS month_name, #week_ref AS week_ref
FROM timesheets ts
WHERE #testDate <= convert(datetime, end_dtm, 120) and
dateadd(wk, 1, #testDate) > convert(datetime, start_dtm, 120)
But the booked time appears to be wrong. Isnt the SUM supposed to calculate the total for each row which are within the start_dtm and end_dtm. So if I have 10 rows with 1 in the booked time you would expect the SUM to be 10.
test data:
SUM calculates the total value of the fields while COUNT is the total number of records.
SELECT description,
COUNT(ts.booked_time) AS booked_time_total,
CONVERT(VARCHAR(11), #testDate, 106) AS month_name,
#week_ref AS week_ref
FROM timesheets ts
WHERE #testDate <= convert(datetime, end_dtm, 120) and
dateadd(wk, 1, #testDate) > convert(datetime, start_dtm, 120)
I think you are looking to use COUNT rather than SUM.