I have a query that gets the yesterday records, but I want that in monday I be able to get the records from friday, not sunday.
Here what I have so far:
select * from tb_interaction
where
(DateInteraction >= DATEADD(day, DATEDIFF(day, 1, GETDATE()), 0)) AND
(DateInteraction < DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0))
Any suggestions?
Thanks!
If your settings are set for English, then you can do:
select i.*
from tb_interaction i cross join
(select (case when datename(getdate()) = 'Monday' then 3
when datename(getdate()) = 'Sunday' then 2
else 1
end) as diff
) x
where DateInteraction >= dateadd(day, - diff - 1, cast(getdate() as date)) and
DateInteraction < dateadd(day, - diff, cast(getdate() as date))
Related
I have a column 'working days' which give info is it working day or no (1 for woking day and 0 for weekend). And the task is to find first 3 working days in each month.
I try to use this code:
SELECT working_day, *
FROM table
WHERE tdate BETWEEN DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0) AND DATEADD(dd, -1, DATEADD(mm, DATEDIFF(mm, -1, GETDATE()), 0))
AND working_day = 1
AND tdate = CAST(GETDATE() AS DATE);
Try using the row_number function as the following:
WITH CTE AS
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY YEAR(tdate), MONTH(tdate) ORDER BY tdate) RN
FROM tbl_name
WHERE working_day = 1
)
SELECT tdate, working_day
FROM CTE
WHERE RN <= 3
Demo
I have a query like this:
select date, count(*)
from inflow
where date >= dateadd(year, -2, getdate())
group by date
order by date
I need to exclude Saturday and Sunday dates, and instead add their counts into the following Monday. What would be the best way to do this? Do I need to exclude Saturday, Sunday, and Mondays, then add them on with a join to a different query? The query above is a simplified version, this is a relatively big query, so I need to keep efficiency in mind.
Well, this is a somewhat brute-force approach:
select date,
(case when datename(weekday, date) = 'Monday')
then cnt + cnt1 + cnt2
else cnt
end) as cnt
from (select date, count(*) as cnt,
lag(count(*), 1, 0) over (order by date) as prev_cnt,
lag(count(*), 2, 0) over (order by date) as prev_cnt2
from inflow
where date >= dateadd(year, -2, getdate())
group by date
) d
where datename(weekday, date) not in ('Saturday', 'Sunday')
order by date;
Note: This is assuming English-language settings so the datename() logic works.
An alternative method without subqueries;
select v.dte, count(*) as cnt
from inflow i cross apply
(values (case when datename(weekday, i.date) = 'Saturday'
then dateadd(day, 2, i.date)
when datename(weekday, i.date) = 'Sunday'
then dateadd(day, 1, 9.date)
else i.date
end)
) v.dte
where i.date >= dateadd(year, -2, getdate())
group by v.dte
order by date;
You state for performance, however without knowing the full picture it's quite hard to understand how to optimise the query.
While I've been working on this, I noticed Gordon Linoff's answer, however I'll continue to write my version up as well, we both following the same path, but get to the answer a little different.
WITH DateData (date, datetoapply)
AS
(
SELECT
[date],
CASE DATEPART(w, [date])
WHEN 5 THEN DATEADD(d, 2, [date])
WHEN 6 THEN DATEADD(d, 1, [date])
ELSE date
END as 'datetoapply'
FROM inflow
WHERE [date] >= dateadd(year, -2, getdate())
)
SELECT datetoapply, count(*)
FROM DateData
GROUP BY datetoapply
ORDER BY datetoapply
While I could not get Gordon's query working as expected, I can confirm that "DATEPART(w, [date])" performs much better than "DATENAME(weekday, [date])", which if replaced in the query above increases the server processing time from 87ms to 181ms based on a table populated with 10k rows in Azure.
I have script for SQL Server that I need to convert to redshift.
Here is part of it, where I have problem with
LEFT JOIN
(SELECT
cog.ClientId,
MAX(CASE me.metrickey WHEN 'contacts-employee_active_count_day_org' THEN mu.value ELSE 0 END) AS ActiveEmployees
FROM
public.module_utilization mu
JOIN
(SELECT
me.id,
me.ChannelId + '-' + me.metrickey AS MetricKey
FROM
public.module_metric me) AS me ON me.id = mu.metricid
LEFT JOIN
public.contacts_client_organization cog ON cog.clientorganizationid = mu.organizationid
WHERE
mu.dy >= DATEADD(Day, -30, GETDATE())
AND me.metrickey IN ('contacts-employee_active_count_day_org')
GROUP BY
cog.clientid) metrics ON metrics.ClientId = be.clientid
WHERE
be.organizationid = 65277
AND be.timeworkedfrom >= DATEADD(MONTH, -6, DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0))
AND be.timeworkedfrom < TO_CHAR(DATE_TRUNC('month', GETDATE()), 'MM/DD/YYYY')
AND be.isdeleted IS NULL
AND be.isvoid IS NULL
At this line
AND be.timeworkedfrom >= DATEADD(MONTH, -6, DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0))
I get this error
Invalid operation: function pg_catalog.date_diff("unknown", integer, timestamp without time zone) does not exist;
As I understood it because of 0
How I can fix this stuff?
Your highlighted WHERE clause logic is comparing timeworkedfrom to a date six months earlier than the first of the current month. You may change this:
AND be.timeworkedfrom >= DATEADD(MONTH, -6, DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0))
to this:
AND be.timeworkedfrom >= date_trunc('month', current_date) - interval '6 month'
Hi i have been trying to put an SQL query together to pull data from 20:00 last night to 8 am today
what i currntly have is however this only selects between 20:00 and 24 because it's only selecting last night what would be the best way to get the results i am looking for?
SELECT COUNT(CardID) AS CardCOUNT
FROM ReaderData
WHERE (controllerID = 28) AND (ReaderTime BETWEEN '20:00:00' AND '08:00:00') AND (CardID = 'fffffff0') AND (DATEDIFF(DAY, DATEADD(DAY, - 1,
CURRENT_TIMESTAMP), dtReading) = 0)
You have split the time from the date so you have to check one time interval for yesterday and another for today.
If you are on SQL Server 2008 and have stored only the date part in dtReading you could use something like this.
select count(R.CardID) as CardCount
from ReaderData as R
where controllerID = 28 and
(
(
R.dtReading = cast(dateadd(day, -1, getdate()) as date) and
R.ReaderTime >= '20:00:00'
) or
(
R.dtReading = cast(getdate() as date) and
R.ReaderTime < '08:00:00'
)
)
Update
With the time values in dtReading it is easier.
Remove the time part from getdate() by casting to date then add the number of hours you want to create the datetime values you want to compare against.
select count(R.CardID) as CardCount
from ReaderData as R
where controllerID = 28 and
R.dtReading >= dateadd(hour, 20, dateadd(day, -1, cast(cast(getdate() as date) as datetime))) and
R.dtReading < dateadd(hour, 8, cast(cast(getdate() as date) as datetime))
I want to modify my Where clause in my SQL Server Query below so that it would select ALL records from the previous month.
Example: if I run the query on 20 Feb, it should extract data for 1 Jan to 31 Jan
I have tried using the following but as you may notice, it picks up the records a month back from the day of execution.
WHERE date_col >= cast(dateadd(Month, -1, getdate()) as date) and
date_col <= cast(getdate() as date)
I'm not claiming this is the best way, but it should work:
SELECT * from YourTable
WHERE DATEPART(Month, date_col) = (DATEPART(Month,GETDATE()) - 1)
AND DATEPART(Year, date_col) = DATEPART(Year,DATEADD(Month, -1, GETDATE()))
Sql Server 2012 and Later
EOMONTH looks like it may be a useful function in this case.
EOMONTH(getdate(), -1) is the end of last month.
EOMONTH(getdate(), -2) is the end of the month before.
Try something like
WHERE date_col >= cast(EOMONTH(getdate(), -1) as date) and date_col <=
cast(EOMONTH(getdate(),-2) as date);
TO get the last and first day of previous month :
SELECT DATEADD(month, DATEDIFF(month, 0, DATEADD(MONTH,-1,GETDATE())), 0) AS First_Day_Of_Last_Month
,DATEADD(s,-1,DATEADD(MONTH, DATEDIFF(MONTH,0,GETDATE()),0)) AS Last_day_Of_Last_Month
Result:
╔═════════════════════════╦═════════════════════════╗
║ First_Day_Of_Last_Month ║ Last_day_Of_Last_Month ║
╠═════════════════════════╬═════════════════════════╣
║ 2014-05-01 00:00:00.000 ║ 2014-05-31 23:59:59.000 ║
╚═════════════════════════╩═════════════════════════╝
Your Query
WHERE date_col >= DATEADD(month, DATEDIFF(month, 0, DATEADD(MONTH,-1,GETDATE())), 0)
AND date_col <= DATEADD(s,-1,DATEADD(MONTH, DATEDIFF(MONTH,0,GETDATE()),0))
Since you want all records from the previous month, you could just compare the month and year parts of the current date and the date_col values, like so:
select *
from yourtable
where
(month(date_col) = month(getdate()) - 1
and year(date_col) = year(getdate())
and month(getdate()) <> 1)
or
(month(date_col) = 12
and year(date_col) = year(getdate()) - 1
and month(getdate()) = 1)
This query also work as already ask by some one and good rating of answer too.
SELECT *
FROM Member
WHERE DATEPART(m, date_created) = DATEPART(m, DATEADD(m, -1, getdate()))
AND DATEPART(yyyy, date_created) = DATEPART(yyyy, DATEADD(m, -1, getdate()))
Get the records of last month in SQL server