How can I get the most recent date in SQL? - sql

I want to make a SQL query that gets todays date and the most recent date from a date column. So if I have three records in my database that have the following dates:
March 8, 2012
March 2, 2012
December 8, 2011
I want the SQL query to return all records for March 8, 2012 and March 2, 2012 (most recent date). How can I do this?
I can date today's date using:
CONVERT( varchar(100), DATEADD( DAY, 0, getdate() ), 111)
Thank You
Edit:
Thanks everyone. I just have one more question. I have created two views:
create view with top dates
CREATE VIEW topDates AS
select DISTINCT TOP 3 replace(CONVERT(VARCHAR(20),date,111),'-','/') AS dates from CSAResults.dbo.Details
create view dateTwo
select *
from (select ROW_NUMBER() over (order by dates desc) as srNo, dates
from topDates)
AS employee
WHERE srNo=2
And now I want to select * from my DB where a column is equal to the 'dates' column from the view 'dateTwo'
select buildNumber
from CSAResults.dbo.Details
where buildNumber LIKE '%Main '+ (SELECT dates FROM dateTwo) + '%'
But this returns nothing.
Thanks

You can do the following:
select date
from yourtable
where
(
date = Convert(varchar(10), getdate(), 101)
OR
date IN (SELECT Max(date)
FROM yourtable
WHERE date!= Convert(varchar(10), getdate(), 101))
)

Here is an example script that does what you are asking. It uses a sub-query to select all records with MAX on the date. You would just add an OR to also select items for the current date.
DECLARE #A TABLE
(
part_no VARCHAR(5),
rev CHAR,
on_hand TINYINT,
safety_stock TINYINT,
so_no VARCHAR(5),
so_date DATETIME
)
INSERT #A
SELECT '12345', 'A', 10, 15, 'S1234', '12/14/2009' UNION ALL
SELECT '12345', 'A', 10, 15, 'S1233', '10/01/2009' UNION ALL
SELECT '12345', 'A', 10, 15, 'S1232', '08/02/2009' UNION ALL
SELECT '12346', '', 5, 0, 'S1231', '08/01/2009' UNION ALL
SELECT '12347', '-', 0, 0, 'S1230', '10/20/2009' UNION ALL
SELECT '12347', '-', 0, 0, 'S1229', '07/15/2009'
SELECT * FROM #A AS A
WHERE so_date =
(
SELECT MAX(so_date)
FROM #A AS B
WHERE B.part_no = A.part_no AND B.Rev = A.Rev
)

SELECT *
INTO #TEMP
FROM
(
SELECT GETDATE() DATE_FIELD, 'Blah1...' OTHER_FIELDS
UNION SELECT GETDATE() DATE_FIELD, 'Blah2...' OTHER_FIELDS
UNION SELECT DATEADD(d,-1,GETDATE()) DATE_FIELD, 'Blah3...' OTHER_FIELDS
UNION SELECT DATEADD(d,-1,GETDATE()) DATE_FIELD, 'Blah4...' OTHER_FIELDS
UNION SELECT DATEADD(d,-3,GETDATE()) DATE_FIELD, 'Blah5...' OTHER_FIELDS
) A
SELECT * FROM #TEMP
SELECT * FROM
(
SELECT DATE_FIELD, OTHER_FIELDS,
DENSE_RANK() OVER (ORDER BY DATE_FIELD DESC) _RANK
FROM #TEMP
) A
WHERE A._RANK < 3

For your second question:
select buildNumber
from CSAResults.dbo.Details
inner join dateTwo
on buildNumber LIKE '%Main '+ dateTwo.dates + '%'

Related

Members within a specific age group within one calendar month

I need to find anyone who was >=6 or <18 per month in 2022.
so for example...even if someone was five on 1/15/2022 and then turned 6 on 1/16/2022 will be counted. or if someone was 17 on 1/20/22 and then turned 18 on 1/21/2022 will still be counted.
im relatively new to sql so any help would be appreciated.
The dates are german format, but you should adapt the logic:
DECLARE #table Table
(kd_id int , birthdate DATE)
INSERT INTO #table
(
kd_id,
birthdate
)
SELECT 1, '01.10.2016'
UNION
SELECT 2, '09.10.2016'
UNION
SELECT 3, '10.10.2016'
UNION
SELECT 4, '11.10.2016'
UNION
SELECT 5, '17.10.2016'
UNION
SELECT 6, '01.10.2004'
UNION
SELECT 7, '09.10.2004'
UNION
SELECT 8, '10.10.2004'
UNION
SELECT 9, '11.10.2004'
UNION
SELECT 10, '17.10.2004'
UNION
SELECT 11, '01.01.2016'
UNION
SELECT 12, '01.01.2004'
UNION
SELECT 13, '01.01.2017'
UNION
SELECT 14, '31.12.2003'
UNION
SELECT 15, '31.12.2003'
UNION
SELECT 16, '31.10.2004'
UNION
SELECT 17, '30.09.2004'
UNION
SELECT 18, '01.11.2016'
--Query
DECLARE #month NVARCHAR(2) = '10' --October
,#year NVARCHAR(4) = '2022'
,#month_begin NVARCHAR(10)
,#month_end NVARCHAR(10)
SET #month_begin = '01.' + #month + '.2022'
SET #month_end = EOMONTH(#month_begin) --EOMONTH() = Last date of a month
SELECT kd_id
,birthdate
FROM #table
WHERE DATEDIFF(hour,birthdate,#month_begin)/8766 BETWEEN 6 AND 17
OR DATEDIFF(hour,birthdate,#month_end)/8766 BETWEEN 6 AND 17

SQL Server : count number of rows per hour

I have a table with 2628 rows in it. I want to get a count per hour. I have a completion_time column which tells the date time of per record.
I can find only one-hour count.
select count(*)
from billing b
where b.completion_time >= '2019-04-16 23:50:23'
and b.completion_time <='2019-04-17 00:50:22'
The date time is up to 9 hours. i.e. the process was started at 2016-04-16 23:50:23 and it ends on 2019-04-17 08:16:49. So I want total counts per hour.
Update 1
I want output like below
How can I achieve it? Any help would be highly appreciated.
Try this:
select datepart(hour,b.completion_time) Hour, count(*) NumberOfRecords
from billing b
group by datepart(hour,b.completion_time)
Edit:
select row_number() over (order by min(b.completion_time)) RowNumber, count(*) NumberOfRecords
from billing b
group by datepart(hour,b.completion_time)
order by min(b.completion_time)
try this.
Declare #StartTime DATETIME = '2016-04-16 23:50:23'
Declare #EndTime DateTime = '2019-04-17 08:16:49'
Declare #Tab Table(id int, Completion_Time DateTime)
Insert into #Tab
SELECT 1, '2016-04-16 23:50:23' Union All
SELECT 2,'2016-04-17 00:50:24' Union All
SELECT 3,'2016-04-17 01:50:26' Union All
SELECT 4,'2016-04-17 01:50:32' Union All
SELECT 5,'2016-04-17 01:50:55' Union All
SELECT 6,'2016-04-17 02:50:28' Union All
SELECT 7,'2016-04-17 02:50:30' Union All
SELECT 8,'2016-04-17 02:50:45' Union All
SELECT 9,'2016-04-17 04:50:32' Union All
SELECT 10,'2016-04-17 04:50:52'
--Select Id, DATEDIFF(HH,#StartTime,Completion_Time) Diff from #Tab
;with cte
As
(
SELECT CONVERT(VARCHAR(5),DATEDIFF(HH,#StartTime,Completion_Time)+1) as [Hour] , COUNT(*) As [Records]
From #Tab
Group by DATEDIFF(HH,#StartTime,Completion_Time)+1
)
Select [Hour] + CASE
WHEN [Hour] % 100 IN (11,12,13) THEN 'th'
WHEN [Hour] % 10 = 1 THEN 'st'
WHEN [Hour] % 10 = 2 THEN 'nd'
WHEN [Hour] % 10 = 3 THEN 'rd'
ELSE 'th'
END + ' hour',
Records
from cte
This will do just what you need :
SELECT HOUR(b.completion_time) hourOfDay, COUNT(*) NumberOfRecords
FROM billing b
GROUP BY hourOfDay
HOUR is a predefined function to calculate hour from a DateTime.

Number of day Count in every week in every month year wise between 2 dates in sql server

I need to get the date and day count values between two dates.
let's suppose, we want to get the records between 1 july to 5 August.
the output should be like below Table image:
we already know that we have 5 weeks in july month and 1 week in august month for this date range :
let's start with first week to last week :
Try this Goutam Singh. I think daycount should now be 7, 2 using the monday as start of the week.
SELECT
[DYear],
[DMonth],
[Week],
DayCount=COUNT(DISTINCT DayCount),
BillableHour=SUM(BillableHour)
FROM
(
SELECT
[DYear]=(YEAR(Workdate)) ,
[DMonth]=(DATENAME(MONTH, Workdate)) ,
DateNames=datename(dw, Workdate),
[Week]='Week ' + CAST((DATEPART(wk,DATEADD(DAY, -1,Workdate)) - MAX(DATEPART(wk,DATEADD(DAY, -1,Workdate)) )over(partition by (select null))+2) AS varchar(20)),
DayCount= ( WorkDate),
BillableHour=(Convert(DECIMAL(16,2),[Hours]))
FROM
#TempTable
WHERE
Workdate between CONVERT(datetime,#FromDate) and CONVERT(datetime,#ToDate)
)G
GROUP BY
[DYear],
[DMonth],
[Week]
Number of days in a week column is not clear to me. otherwise, below will be the query. Just replace value and date columns with your appropriate column names.
select count(value),month(date),datepart(WEEKDAY,date()) as number of week,date
from t
group by date
#Goutam Singh I have here an updated version. Basically, you need a CTE to build a template table for your query and then do a join depending on what is in the table you want to get the TotalHours. Let me know if that is what you want.
DECLARE #StartDate DATE='20180101'
DECLARE #EndDate DATE='20180901'
DECLARE #Dates TABLE(
Workdate DATE Primary Key
)
DECLARE #TempTable TABLE (Id INT, Hours real, WorkDate DATETIME )
INSERT INTO #TempTable
SELECT 1, 5, '03.05.2018 00:00:00' UNION ALL
SELECT 2, 1.5, '08.05.2018 00:00:00' UNION ALL
SELECT 3, 3, '01.05.2018 00:00:00' UNION ALL
SELECT 4, 0, '04.05.2018 00:00:00' UNION ALL
SELECT 5, 2, '03.05.2018 00:00:00' UNION ALL
SELECT 6, 4, '03.05.2018 00:00:00' UNION ALL
SELECT 7, 2, '05.05.2018 00:00:00' UNION ALL
SELECT 8, 0.5, '08.05.2018 00:00:00' UNION ALL
SELECT 9, 0, '01.05.2018 00:00:00' UNION ALL
SELECT 10, 6, '08.05.2018 00:00:00' UNION ALL
SELECT 11, 8, '02.05.2018 00:00:00' UNION ALL
SELECT 12, 3.5, '09.05.2018 00:00:00' UNION ALL
SELECT 13, 1, '09.05.2018 00:00:00' UNION ALL
SELECT 14, 4, '04.05.2018 00:00:00' UNION ALL
SELECT 15, 1, '03.05.2018 00:00:00' UNION ALL
SELECT 16, 0, '02.05.2018 00:00:00' UNION ALL
SELECT 17, 3, '05.05.2018 00:00:00' UNION ALL
SELECT 18, 0.5, '04.05.2018 00:00:00' UNION ALL
SELECT 19, 2, '09.05.2018 00:00:00' UNION ALL
SELECT 20, 0, '09.05.2018 00:00:00'
--DATEADD(DAY, -1,Workdate)
;WITH Dates AS(
SELECT Workdate=#StartDate,WorkMonth=DATENAME(MONTH,#StartDate),WorkYear=YEAR(#StartDate), WorkWeek=datename(wk, DateAdd(DAY,-1,#StartDate) )
UNION ALL
SELECT CurrDate=DateAdd(DAY,1,Workdate),WorkMonth=DATENAME(MONTH,DateAdd(DAY,1,Workdate)),YEAR(DateAdd(DAY,1,Workdate)),datename(wk, Workdate) FROM Dates D WHERE Workdate<#EndDate ---AND (DATENAME(MONTH,D.Workdate))=(DATENAME(MONTH,D.Workdate))
)
SELECT
WorkMonth,
NumWeek=ROW_NUMBER()OVER(PARTITION BY WorkMonth+cast(WorkYear as varchar(20)) ORDER BY WorkdateStart),
NumDayWeek,
WorkYear,
WorkdateStart,
WorkdateEnd,
TotalHours=SUM(TotalHours)
FROM
(
SELECT
D.Workdate,
D.WorkMonth,
D.WorkYear,
D.WorkWeek,
WorkdateStart=MIN(D.Workdate) over(partition by cast(WorkWeek as varchar(20))+workmonth+cast(WorkYear as varchar(20))),
WorkdateEnd=MAX(D.Workdate) over(partition by cast(WorkWeek as varchar(20))+workmonth+cast(WorkYear as varchar(20))),
NumDayWeek=datediff(day,MIN(D.Workdate) over(partition by cast(D.WorkWeek as varchar(20))+workmonth+cast(WorkYear as varchar(20))),MAX(D.Workdate) over(partition by cast(D.WorkWeek as varchar(20))+workmonth+cast(WorkYear as varchar(20))))+1,
T.TotalHours,
T.DayCount
FROM
Dates D
LEFT JOIN
(
SELECT T.WorkDate, TotalHours=sum(T.Hours), DayCount=sum(case when T.Hours>0 then 1 else 0 end) FROM
#TempTable T
GROUP BY
T.WorkDate
)T ON
T.WorkDate = D.Workdate
)Sub
GROUP BY
WorkMonth,
WorkYear,
WorkdateStart,
NumDayWeek,
WorkdateEnd
ORDER BY
WorkdateStart
option (maxrecursion 0)

Return records less than date

I have a table where 2 columns are called Month and Year and are both INT. I need to return all the records that are less than the date provided.
So if I pass the following parameters #Month = 8 and #Year = 2017, I would like to return all records before August 2017. What is the best way to achieve this?
SELECT * FROM testTable
WHERE year <= #Year AND
month < #Month
is my current SQL. This won't work if I need to display the record that is November 2014
Compare them as dates. Like this:
SELECT * FROM testTable
WHERE DATEFROMPARTS(year, month, 1) <= DATEFROMPARTS(#Year, #Month, 1)
Pass The Parameter as Date. Like
DECLARE #MyDate DATE = '08-01-2014'
Now you can go for either of the below
SELECT
*
FROM YourTable
WHERE CAST(ConCAT([Monnth],'-01-',[Year]) AS DATE) = #MyDate
Or
SELECT
*
FROM YourTable
WHERE [Year] = YEAR(#MyDate)
AND [Month] = MONTH(#MyDate)
You can use DATEPART function of SQL Server
SELECT * FROM testTable
WHERE YEAR<= DATEPART(yy,yourdate) AND
MONTH < DATEPART(mm,yourdate)
It would be better to convert data types and query further.
DECLARE #testtable TABLE (id INT identity(1, 1), name VARCHAR(100), year INT, month INT)
INSERT INTO #testtable (name, year, month)
SELECT 'me', '2014', 10
UNION
SELECT 'you', '2017', 08
UNION
SELECT 'us', '2015', 10
UNION
SELECT 'Him', '2017', 10
UNION
SELECT 'Her', '2018', 1
SELECT *
FROM #testtable
WHERE CONCAT (year, '-', right('00' + cast(Month AS VARCHAR(2)), 2), '-', '01')
< = '2017-08-01'

converting varchar to date/Using isdate()

I have a flat file that I am importing into a SQL Server 2005 staging table as character data.
I need to convert the birthday field to datetime format when copying it to the final destination table. I was doing so using the following:
BIRTHDAY = case when isdate(DOB)=1 then convert(datetime, '19'+right(DOB, 2)+left(DOB, 2)+substring(DOB,3,2)) else null end
The problem is only 100+ of the birthdays from the 32k+ file are identified as dates.
I cannot see a difference between the ones that are dates and the ones that aren't. I have included a sampling below.
good date bad date
41129 100465
10531 122467
10429 20252
81030 62661
31231 20959
11028 91965
80928 60665
Looks like the raw data is in MMDDYY, but the months are not 0-padded.
Building on this assumption, you can parse the date parts like below and rebuild a datetime:
declare #raw table (dob varchar(100));
insert into #raw
select '41129' union all
select '10531' union all
select '10429' union all
select '81030' union all
select '31231' union all
select '11028' union all
select '80928' union all
select '100465' union all
select '122467' union all
select '20252' union all
select '62661' union all
select '20959' union all
select '91965' union all
select '60665'
select *,
[asDate] = dateadd(day, dd - 1, dateadd(month, mm - 1, dateadd(year, ('19' + yy)-1900, 0)))
from ( select dob,
substring(right('0' + dob, 6), 1, 2),
substring(right('0' + dob, 6), 3, 2),
substring(right('0' + dob, 6), 5, 2)
from #raw
) as stage (string, mm, dd, yy);