I have a column of date values that are currently of type varchar. Could someone please explain the easiest way to convert these to actual dates. Below is a list of example values in the aforementioned column
- Expiration Date
- 00/00/00
- 11/06/10
- 00/00/00
- 29/02/08
- 01/04/11
NOTE: 00/00/00 means there is no expiration date, but they still need to be included somehow as I store other data on them.
Your data appears to be in dd/mm/yy format, so use convert() with format code 3:
select try_convert(date, str, 3)
Try this:
select case yourVarcharValue when '00/00/00' then NULL else Try_Convert(Date, yourVarcharValue)
In that case, need to select from converted results:
declare #myTable table(ExpirationDate varchar(max))
insert into #myTable (ExpirationDate ) values ('00/00/00')
insert into #myTable (ExpirationDate) values ('11/06/10')
insert into #myTable (ExpirationDate) values ('29/02/08')
insert into #myTable (ExpirationDate) values ('01/04/11')
select ExpirationDate from
(
select ISNULL(try_convert(date, ExpirationDate, 3), '9999-12-31') as ExpirationDate
from #myTable) d
order by d.ExpirationDate asc
Results:
ExpirationDate
2008-02-29
2010-06-11
2011-04-01
9999-12-31
I highly recommend you to not store Date fields as NVARCHAR/VARCHAR:
select ISNULL(try_convert(date, ExpirationDate, 3), '9999-12-31') from myTable
SQL Fiddle
MS SQL Server 2017 Schema Setup:
create table myTable (ExpirationDate varchar(max))
insert into myTable (ExpirationDate ) values ('00/00/00')
insert into myTable (ExpirationDate) values ('11/06/10')
insert into myTable (ExpirationDate) values ('29/02/08')
insert into myTable (ExpirationDate) values ('01/04/11')
Query 1:
select ISNULL(try_convert(date, ExpirationDate, 3), '9999-12-31') from myTable
Results:
| |
|------------|
| 9999-12-31 |
| 2010-06-11 |
| 2008-02-29 |
| 2011-04-01 |
Related
This is my query:
declare #t table (date1 date,date2 date,date3 date)
insert into #t values ('2019-01-01','2019-01-20','2019-02-10')
insert into #t values (null,null,'2019-02-01')
insert into #t values (null,'2019-02-01','2019-02-02')
My expected output is:
2019-02-10
2019-02-01
2019-02-02
I tried to use coalesce like :
select coalesce(date1,date2,date3) as maxdate from #t
I know coalesce returns first not null value. So what I can do to get my desired result.
This will do the trick.
Basically you transform every row in a data-set, using VALUES clause, and then just get the MAX value.
SELECT (
SELECT MAX(LastUpdateDate)
FROM (VALUES (date1),(date2),(date3)) AS UpdateDate(LastUpdateDate)) AS LastUpdateDate
FROM #t
coalesce() has nothing to do with this. Unfortunately, SQL Server does not support greatest(). But you can use apply:
select t.*, m.max_date
from #t t cross apply
(select max(dte) as max_date
from (values (t.date1), (t.date2), (t.date3)) v(dte)
) m;
The max() ignores NULL values, so this does what you expect.
Here is a db<>fiddle.
Personally I would normalise your data, by unpivoting it, and then getting the MAX in the group. This does, however, require you have some kind of column to identify the row (I use an IDENTITY in this example):
DECLARE #t table (id int IDENTITY,
date1 date,
date2 date,
date3 date);
INSERT INTO #t
VALUES ('2019-01-01', '2019-01-20', '2019-02-10');
INSERT INTO #t
VALUES (NULL, NULL, '2019-02-01');
INSERT INTO #t
VALUES (NULL, '2019-02-01', '2019-02-02');
SELECT MAX([date])
FROM #t t
CROSS APPLY (VALUES(t.date1),(date2),(t.date3))V([date])
GROUP BY t.id;
I am working with SQL Server & PHP and using stored procedures.
I have a table called myTable. I has a column start_time (DateTime Format).
start_time
-----------------------
2019-05-23 12:20:22.000
2019-08-02 01:21:02.000
2019-02-10 22:32:17.000
2019-08-14 04:56:24.000
I want to filter results by time only.
For-example: BETWEEN 22:20:10.000 AND 04:56:24.000
But, It's not Working.
Simple casting to time datatype will work:
select * from myTable
where cast(start_time as time) >= '22:00:00.000'
or cast(start_time as time) <= '04:00:00.000'
Note that applying a CAST function to the start_time column in the WHERE clause predicate will prevent an index that column from being used efficiently. A full table scan will be required unless other criteria are specified.
this code will work please check
create table #temp
(
[Date] datetime
)
insert into #temp values ('2019-05-23 12:20:22.000')
insert into #temp values ('2019-08-02 01:21:02.000')
insert into #temp values ('2019-02-10 22:32:17.000')
insert into #temp values ('2019-08-14 04:56:24.000')
select cast([Date] as date) as [Date],convert(char(15), [Date], 108) [Time]
from #temp
where convert(char(15), [Date], 108) between '04:56:24' and '22:32:17'
Drop table #temp
I have a column price datatype is nvarchar because I save thousand seperator with comma like 1,000,000.00. I now need to select convert and sum it in select statement then display group by id in crystalreport.
My select statement:
select id,productname,type,price,datesell,seller from tb_billdetail group by id
Here I need how to convert the price from nvarchar to type double and sum it after converted but just using select statement?
Something I need to display in crystal report like:
col_id col_name col_type col_price col_date
**001**
001 fish food 20,000.00 01/02/2018
001 fish food 10,000.00 10/02/2018
col_sum id 001: 30,000.00
next group id 002 and 003 ....
Declare #tt table (name nvarchar(10), value nvarchar(10))
insert into #tt (name, value) values ('a', '1,000')
insert into #tt (name, value) values ('a', '1,10,000')
insert into #tt (name, value) values ('b', '2,000.4223')
insert into #tt (name, value) values ('b', '4,000.2')
select name, sum(cast(REPLACE(value,',','') as float)) as sum from #tt group by name
it's not a good idea to store with comma separate, store it's as the decimal.
If your storing comma for displaying purpose then add it when displaying.
Using SQL Server 2005/2008 I would like to insert a new row if the last value (sorted by _timestamp) inserted is not the same value.
For example:
value | timestamp
100 | "yesterday"
101 | "today"
For the next operation:
A value of 101 should not be inserted as this is the latest value
However a value of 102 should be inserted as the latest value is not this
Why you don't use something like that?
DECLARE #table TABLE(val INT, [timestamp] DATETIME)
INSERT INTO #table
SELECT 100, N'20160112'
UNION ALL
SELECT 101, N'20160113'
SELECT * FROM #table
INSERT INTO #table
SELECT 101, N'20160114'
WHERE 101 <> ISNULL((SELECT TOP 1 val FROM #table
ORDER BY timestamp DESC), -1)
SELECT * FROM #table AS T
I'm trying to retrieve the latest set of rows from a source table containing a foreign key, a date and other fields present. A sample set of data could be:
create table #tmp (primaryId int, foreignKeyId int, startDate datetime,
otherfield varchar(50))
insert into #tmp values (1, 1, '1 jan 2010', 'test 1')
insert into #tmp values (2, 1, '1 jan 2011', 'test 2')
insert into #tmp values (3, 2, '1 jan 2013', 'test 3')
insert into #tmp values (4, 2, '1 jan 2012', 'test 4')
The form of data that I'm hoping to retrieve is:
foreignKeyId maxStartDate otherfield
------------ ----------------------- -------------------------------------------
1 2011-01-01 00:00:00.000 test 2
2 2013-01-01 00:00:00.000 test 3
That is, just one row per foreignKeyId showing the latest start date and associated other fields - the primaryId is irrelevant.
I've managed to come up with:
select t.foreignKeyId, t.startDate, t.otherField from #tmp t
inner join (
select foreignKeyId, max(startDate) as maxStartDate
from #tmp
group by foreignKeyId
) s
on t.foreignKeyId = s.foreignKeyId and s.maxStartDate = t.startDate
but (a) this uses inner queries, which I suspect may lead to performance issues, and (b) it gives repeated rows if two rows in the original table have the same foreignKeyId and startDate.
Is there a query that will return just the first match for each foreign key and start date?
Depending on your sql server version, try the following:
select *
from (
select *, rnum = ROW_NUMBER() over (
partition by #tmp.foreignKeyId
order by #tmp.startDate desc)
from #tmp
) t
where t.rnum = 1
If you wanted to fix your attempt as opposed to re-engineering it then
select t.foreignKeyId, t.startDate, t.otherField from #tmp t
inner join (
select foreignKeyId, max(startDate) as maxStartDate, max(PrimaryId) as Latest
from #tmp
group by foreignKeyId
) s
on t.primaryId = s.latest
would have done the job, assuming PrimaryID increases over time.
Qualms about inner query would have been laid to rest as well assuming some indexes.