I'm looking to update the SOLUTION_ID where the CREATED_DATE is Greater Than or Equal To the given date.
What I have so far is updating all the records in the Table. CREATED_DATE has a smalldatetime datatype.
UPDATE [Database].[dbo].[TB__TABLE]
SET SOLUTION_ID = 1
WHERE CAST(CREATED_DATE AS datetime) >= 2011-05-08
Help greatly appreciated!
You want to quote the date;
WHERE CREATED_DATE >= '2011-05-08'
(unquoted 2011-05-08 is treated as a mathematical expression that evaluates to 1998)
Casting of column with smalldatetime is not required. Please see below the sample
create table #temp
(
dat smalldatetime,
Solution_ID int
)
insert into #temp(dat, Solution_ID)values(1, GETDATE())
insert into #temp(dat, Solution_ID)values(2, GETDATE()+1)
insert into #temp(dat, Solution_ID)values(3, GETDATE()+2)
select * from #temp
where dat >= 'Your date'
Update #temp
Set Solution_ID = 4
Where dat >= 'Your date'
UPDATE [Database].[dbo].[TB__TABLE]
SET SOLUTION_ID = 1
WHERE CAST(CREATED_DATE AS datetime) >= '2011-05-08'
No need for the cast at all.
And your query won't work exactly as you expect in that 2011 - 5 - 8 = 1998 which in sql server is 22/6/1905...
>= '2011-05-08'
Use the DATEDIFF function
DATEDIFF(dd, #GIVEN_DATE, CREATED_DATE) >= 0
This will return the number of days difference from your given date and your created date. When the function returns zero or greater, then the created_date is greater than the given date. No need for casting.
UPDATE [Database].[dbo].[TB__TABLE]
SET SOLUTION_ID = 1
WHERE DATEDIFF(dd, #GIVEN_DATE, CREATED_DATE) >= 0
Related
I am using SQL server. I'm trying to ad a condition that gives me the rows where the difference is date is between 0-3 or if something was opened 0-3 days after the migration date.
When I added the condition to the WHERE clause it acting funcky. I need help figuring out the best way to do this
This give me a result where the date diff is less than 0 even though I say >= 0
select * from table_1
where datediff(day, a.[opened date], d.[UserMigratedDate]) >= 0
This give me a result where the date diff is greater than 4 even though I say < 4
select * from table_1
where datediff(day, a.[opened date], d.[UserMigratedDate]) < 4
When I use a between it does noting. Am I doing this wrong?
select * from table_1
where (datediff(day, a.[opened date], d.[UserMigratedDate]) >= 0 and datediff(day, a.[opened date], d.[UserMigratedDate]) < 4)
I would like to see your test data that's causing this... because the where clause is constructed correctly. Take the below case for example. ID 2-5 will be returned. Also, your first datediff() where you are seeing if the days are >=0 doesn't make sense to be unless someone could migrate something before it was opened...
http://rextester.com/UTLX59878
declare #table table (id int, openedDate datetime, UserMigratedDate datetime)
insert into #table
values
(1,'2017-01-01','2016-12-31'), --this technically shouldn't happen
(2,'2017-01-01','2017-01-01'),
(3,'2017-01-01','2017-01-02'),
(4,'2017-01-01','2017-01-03'),
(5,'2017-01-01','2017-01-04'),
(6,'2017-01-01','2017-01-05')
select
*,
datediff(day, openedDate, UserMigratedDate) as theDateDiff
from #table
where
datediff(day, openedDate, UserMigratedDate) >= 0
and
datediff(day, openedDate, UserMigratedDate) < 4
I have a large Type 2 Dimension table and causing performance issues in the select queries...I want to limit the Dimensions based on the report Start and End Dates ...But I am struggling to get the right query for that...Here is an example of what I am looking for...
declare #DimCustomers table (CKey int, ID nvarchar(20), Customer nvarchar(50), StartDate datetime, EndDate datetime)
insert into #DimCustomers values
(100, 'C1', 'Customer1', '2010-01-01', '2010-12-31'),
(101, 'C1', 'xCustomer1', '2011-01-01', '2011-12-31'),
(102, 'C1', 'xxCustomer1', '2012-01-01', '2012-12-31'),
(103, 'C1', 'xxxCustomer1', '2013-01-01', NULL)
declare #ReportStartDate datetime = '2010-05-01', #ReportEndDate datetime = '2011-03-01'
select
* from #DimCustomers
The expectation is that when someone runs a report between '2010-02-01' and '2011-02-01', I get an out put for Ckey 100 and 101.
For a report between '2011-02-01' and current date -> 101, 102 and 103
For a report between '2015-02-01' and current date -> 103
I hope that explains what I am looking for...how should my WHERE clause look like on the #DimCustomers?
Thanks
Note: I do not want to join with the Fact Table to start with...
You have NULL value in EndDate. You will have to deal with it.
For example:
SELECT *
FROM #DimCustomers
WHERE StartDate >= #ReportStartDate
AND ISNULL(EndDate,GETDATE()) <= #ReportEndDate
select
*
from
#DimCustomers
where
--gets where #ReportStartDate falls in range
(#ReportStartDate >= StartDate and #ReportStartDate <= isnull(EndDate,getdate()))
or
--gets where #ReportEndDate falls in range
(#ReportEndDate <= isnull(EndDate,getdate()) and #ReportEndDate >= StartDate)
or
--gets where the range in data falls inside parameter range
(#ReportStartDate < StartDate and #ReportEndDate > isnull(EndDate,getdate()))
DECLARE #startMonth int
DECLARE #endMonth int
DECLARE #startYear int
DECLARE #endYear int
SET #startMonth = 1
SET #endMonth =5
SET #startYear =2014
SET #endYear =2015
SELECT * FROM Table
WHERE (YEAR(Date)>=#startYear AND MONTH(Date) >= #startMonth)
AND (YEAR(Date)<=#endYear AND MONTH(Date) <= #endMonth)
This is apparently returning results of any date between 2014-01-01 to 2014-05-31
and 2014-01-01 to 2015-05-31
but I would like to get any date from 2014-01-01 to 2015-05-31 instead.
How should I change the query? I should write the following?
SELECT * FROM Table
WHERE Date>=DATEFROMPARTS ( #startYear, #startMonth, 1 )
AND Date <= DATEFROMPARTS ( #endYear, #endMonth, 31 ))
Then I end up with the problem that if the #endMonth does not contain 31 days. Then I would have to create another checking to ensure the correct number of end date.
I am sure there must be a better way of writing this. I would appreciate your help.
SELECT *
FROM your_table
WHERE Date >= DATEFROMPARTS(#startYear, #startMonth, 1)
AND Date < DATEFROMPARTS(#endYear, #endMonth + 1, 1)
SELECT *
FROM
<table_name>
WHERE
date BETWEEN DATEFROMPARTS(#startYear,#startMonth,1) AND EOMONTH(DATEFROMPARTS(#endYear,#endMonth,1));
I have a table in MSSQL with the following structure:
PersonId
StartDate
EndDate
I need to be able to show the number of distinct people in the table within a date range or at a given date.
As an example i need to show on a daily basis the totals per day, e.g. if we have 2 entries on the 1st June, 3 on the 2nd June and 1 on the 3rd June the system should show the following result:
1st June: 2
2nd June: 5
3rd June: 6
If however e.g. on of the entries on the 2nd June also has an end date that is 2nd June then the 3rd June result would show just 5.
Would someone be able to assist with this.
Thanks
UPDATE
This is what i have so far which seems to work. Is there a better solution though as my solution only gets me employed figures. I also need unemployed on another column - unemployed would mean either no entry in the table or date not between and no other entry as employed.
CREATE TABLE #Temp(CountTotal int NOT NULL, CountDate datetime NOT NULL);
DECLARE #StartDT DATETIME
SET #StartDT = '2015-01-01 00:00:00'
WHILE #StartDT < '2015-08-31 00:00:00'
BEGIN
INSERT INTO #Temp(CountTotal, CountDate)
SELECT COUNT(DISTINCT PERSON.Id) AS CountTotal, #StartDT AS CountDate FROM PERSON
INNER JOIN DATA_INPUT_CHANGE_LOG ON PERSON.DataInputTypeId = DATA_INPUT_CHANGE_LOG.DataInputTypeId AND PERSON.Id = DATA_INPUT_CHANGE_LOG.DataItemId
LEFT OUTER JOIN PERSON_EMPLOYMENT ON PERSON.Id = PERSON_EMPLOYMENT.PersonId
WHERE PERSON.Id > 0 AND DATA_INPUT_CHANGE_LOG.Hidden = '0' AND DATA_INPUT_CHANGE_LOG.Approved = '1'
AND ((PERSON_EMPLOYMENT.StartDate <= DATEADD(MONTH,1,#StartDT) AND PERSON_EMPLOYMENT.EndDate IS NULL)
OR (#StartDT BETWEEN PERSON_EMPLOYMENT.StartDate AND PERSON_EMPLOYMENT.EndDate) AND PERSON_EMPLOYMENT.EndDate IS NOT NULL)
SET #StartDT = DATEADD(MONTH,1,#StartDT)
END
select * from #Temp
drop TABLE #Temp
You can use the following query. The cte part is to generate a set of serial dates between the start date and end date.
DECLARE #ViewStartDate DATETIME
DECLARE #ViewEndDate DATETIME
SET #ViewStartDate = '2015-01-01 00:00:00.000';
SET #ViewEndDate = '2015-02-25 00:00:00.000';
;WITH Dates([Date])
AS
(
SELECT #ViewStartDate
UNION ALL
SELECT DATEADD(DAY, 1,Date)
FROM Dates
WHERE DATEADD(DAY, 1,Date) <= #ViewEndDate
)
SELECT [Date], COUNT(*)
FROM Dates
LEFT JOIN PersonData ON Dates.Date >= PersonData.StartDate
AND Dates.Date <= PersonData.EndDate
GROUP By [Date]
Replace the PersonData with your table name
If startdate and enddate columns can be null, then you need to add
addditional conditions to the join
It assumes one person has only one record in the same date range
You could do this by creating data where every start date is a +1 event and end date is -1 and then calculate a running total on top of that.
For example if your data is something like this
PersonId StartDate EndDate
1 20150101 20150201
2 20150102 20150115
3 20150101
You first create a data set that looks like this:
EventDate ChangeValue
20150101 +2
20150102 +1
20150115 -1
20150201 -1
And if you use running total, you'll get this:
EventDate Total
2015-01-01 2
2015-01-02 3
2015-01-15 2
2015-02-01 1
You can get it with something like this:
select
p.eventdate,
sum(p.changevalue) over (order by p.eventdate asc) as total
from
(
select startdate as eventdate, sum(1) as changevalue from personnel group by startdate
union all
select enddate, sum(-1) from personnel where enddate is not null group by enddate
) p
order by p.eventdate asc
Having window function with sum() requires SQL Server 2012. If you're using older version, you can check other options for running totals.
My example in SQL Fiddle
If you have dates that don't have any events and you need to show those too, then the best option is probably to create a separate table of dates for the whole range you'll ever need, for example 1.1.2000 - 31.12.2099.
-- Edit --
To get count for a specific day, it's possible use the same logic, but just sum everything up to that day:
declare #eventdate date
set #eventdate = '20150117'
select
sum(p.changevalue)
from
(
select startdate as eventdate, 1 as changevalue from personnel
where startdate <= #eventdate
union all
select enddate, -1 from personnel
where enddate < #eventdate
) p
Hopefully this is ok, can't test since SQL Fiddle seems to be unavailable.
I have a datetime column - createddatetime with this value 2015-02-10 23:54:02.000
All I have to do is to compare ONLY THE DATE with getdate() function (Time can be ignored)
How should the query be written.
the pseudo query is:
select * from table where createddatetime(only date) = getdate(only date)
USE CAST or CONVERT function:
select * from table where cast(createddatetime as date) = cast(getdate() as date)
Lots of ways. My favorite is with DATEDIFF()
SELECT * FROM Table WHERE DATEDIFF(day,createddatetime,getdate()) = 0