Need to convert a numeric field to date in this query - sql

I am running this in sql server but there is an error on the date compare as the column cadodt is a numeric. Is there a quick and easy way to convert that col to numeric? It's date is in YYYYMMDD but I cannot compare against a date field like current date.
select * from openquery(IBSIBM, 'select CABANO, CABCRC, CABCTR, CABCUR, CABKCO, CACLVL, CACOTI,
CACRDT, CACTTP, CADODT, CADOTY, CAEXRT, CAIDNO, CAJONO, CANCRX,
CAPERI, CAREFX, CARSCD, CASCRC, CASCTR, CASTAT, CASTMT, CASYID,
CATIML, CATREF, CATTXT, CATYPC, CAUSER, CAVADT, CAVODT, CAVONO,
CAVOTY ,NANAME from CA1665AFCV.SROCBA,
CA1665AFCV.srolta,
CA1665AFCV.sronam
WHERE CADOTY = ''CHK'' and cajono=ctjono and cadodt = CURRENT DATE()
and caperi=ctperi and caidno=ctidno and ctveno=nanum
and CASTAT = ''Y''')

Assuming cadodt is actually an integer or numeric field and not a character string, try this:
select * from openquery(IBSIBM,
'select CABANO, CABCRC, CABCTR, CABCUR, CABKCO, CACLVL, CACOTI,
CACRDT, CACTTP, CADODT, CADOTY, CAEXRT, CAIDNO, CAJONO, CANCRX,
CAPERI, CAREFX, CARSCD, CASCRC, CASCTR, CASTAT, CASTMT, CASYID,
CATIML, CATREF, CATTXT, CATYPC, CAUSER, CAVADT, CAVODT, CAVONO,
CAVOTY, NANAME
from CA1665AFCV.SROCBA, CA1665AFCV.srolta, CA1665AFCV.sronam
WHERE CADOTY = ''CHK''
and cajono = ctjono
and cadodt = YEAR(CURRENT DATE) * 10000 + MONTH(CURRENT DATE) * 100 + DAY(CURRENT DATE)
and caperi = ctperi
and caidno = ctidno
and ctveno = nanum
and CASTAT = ''Y''')
Aside: I would strongly recommend against using comma joins. The longer ANSI 92 join syntax is much easier to read and maintain. I'd also strongly recommend using qualified column names. This schema is not the easiest to follow as it is. No need to make it even more arcane.

You have these options
convert cadodt from string to date
convert cadodt from intger to date
convert current date to YYYYMMDD string
convert current date to YYYYMMDD integer
1 and 3 assume cadodt is a string
2 and 4 assume cadodt is an intger
3 and 4 are the more efficient approaches as you only change one value.
e.g.
(3) if cadodt is a string in YYYMMDD format:
AND cadodt = VARCHAR_FORMAT(CURRENT DATE, 'YYYYMMDD')
(4) if cadodt is an integer representing YYYYMMDD
AND cadodt = YEAR(CURRENT DATE) * 10000 + MONTH(CURRENT DATE) * 100 + DAY(CURRENT DATE)

the CURRENT DATE() may be causing you some issues use CURRENT_DATE()
Try this:
select * from openquery(IBSIBM, 'select CABANO, CABCRC, CABCTR, CABCUR, CABKCO, CACLVL, CACOTI,
CACRDT, CACTTP, CADODT, CADOTY, CAEXRT, CAIDNO, CAJONO, CANCRX,
CAPERI, CAREFX, CARSCD, CASCRC, CASCTR, CASTAT, CASTMT, CASYID,
CATIML, CATREF, CATTXT, CATYPC, CAUSER, CAVADT, CAVODT, CAVONO,
CAVOTY ,NANAME from CA1665AFCV.SROCBA,
CA1665AFCV.srolta,
CA1665AFCV.sronam
WHERE CADOTY = ''CHK'' and cajono=ctjono and cadodt = CURRENT_DATE()
and caperi=ctperi and caidno=ctidno and ctveno=nanum
and CASTAT = ''Y''')

Replace CADODT = CURRENT DATE() with:
date(substr(char(CADODT), 1, 4) || '-'|| substr(char(CADODT),5, 2) || '-'|| substr(char(CADODT), 7, 2)) = CURRENT DATE
That should convert it from an integer to a date.

Related

SQL code to find between Days only. Not dates

I am trying to execute the code but it throws me an error. I need the days to be between 7 and 10
I have already tried running it but it is not working so far
select * from hive.entity.bookings_base_fact where car_number in('S424BFK',
'S275BCK',
'S257CAN',
'BANDYS',
'722YKE',
'427YNZ',
'042XUK',
'161YKD',
'029YHY',
'894VIF',
'856XHF',
'ALG16',
'364TGB',
'452YTB',
'171WSN',
'148YIC',
'599XPY',
'ZAG386',
'1LX5FU',
'1PC7PW',
'VISNOI',
'1BO1RQ',
'ZCI076',
'1LX6DH',
'ZSF986',
'1EIR205',
'1GKX072',
'RAKHRA',
'1GRK465',
'1EQO445',
'1EKU643',
'1DXD359',
'1EXA622',
'1DSJ769',
'SINGH001',
'A77027',
'1GOV986',
'1GBY431',
'1EDN031',
'1DUH537',
'1DIY218',
'WAN813',
'1DYR270',
'1ERI764',
'1DVS953',
'1GTW217',
'1GFD951',
'1ETD570',
'1GJG518',
'1GJI460',
'MIGLANI',
'1GHI708',
'1GPQ808',
'1GPT618',
'1EGF910',
'1ELU000',
'1GPP664',
'1GSF834',
'WA23600',
'1EPO234',
'1DYQ191',
'1EFG503',
'1EGK697',
'1EWY165',
'1EIX170',
'1GDP522',
'1GTP444',
'1DGF516',
'1DPC526',
'1EQM261',
'1EVC862',
'1GBX209',
'1GKZ876',
'1GNG683',
'1EEZ674',
'1GPO491',
'1EVB911',
'1GUP612',
'BV31RJ',
'CRQ71X',
'CT99PU',
'EAW37E',
'CYN07E',
'BWN62F',
'DNW45H',
'DFS57K',
'DVS85L',
'CL43PE',
'BNO46F',
'CZL21R',
'BH60VR',
'CM16EE',
'YJB08D',
'CO10RJ',
'DYW67H',
'DXL39P',
'CA10BZ',
'DWE07J',
'BV73JU',
'DPK94X',
'CJJ39S',
'CJH53E',
'CO33KZ',
'CU14BL',
'DZK23F',
'CD68JB',
'CVA62V',
'DKR25C',
'CP61CE',
'CQ55MZ',
'YCP92Y',
'DVQ94B',
'BWD26H',
'DWG35Q',
'YIV33C',
'DSN50W',
'CQ92MT',
'DXV29V',
'CHT08L',
'EAV95U',
'BN99CL',
'PTI786',
'CQ74YA',
'CK62MQ',
'CA70CH',
'CQ78UB',
'CN46RX',
'CL83WY',
'CM05DI',
'BU30HV',
'CGT93H',
'CM06TN',
'DVZ41R',
'CS35QM',
'CT03AY',
'YCP71P',
'BPI07J',
'CL43SH',
'DXV62T',
'CA99ME',
'YIU86L',
'YDE45J',
'CO96PR',
'EBN83B',
'BX19FX',
'YJK59F',
'DZB28E',
'BW50MZ',
'CK80MR',
) and year=2019 and month=06 and day between 7 and 10
I suggest you to store dates in a date column with a DATE format, so you can use native functions and do your query like this :
WHERE YEAR(date) = 2019
AND MONTH(date) = 6
AND DAY(date) BETWEEN 7 AND 10
But in your case, I think your columns use strings, you can do this :
WHERE CAST(year AS INT) = 2019
AND CAST(month AS INT) = 6
AND CAST(day AS INT) BETWEEN 7 AND 10
Try to convert columns to datatype integer in the following:
and cast(year as int) = 2019
and cast(month as int) = 6
and cast(day as int) between 7 and 10
The use of the leading zeros in the integers suggests that the columns are actually strings. If this is the case, then the comparisons should be as strings:
year = '2019' and month = '06' and
day between '07' and '10'

SQL Code = -420 Invalid character found in a character string argument of the function "decfloat"

I am having trouble with this code.
(SELECT r.SITE_ID, count(distinct r.NIIN)
FROM
(SELECT t.SITE_ID, t.NIIN, B.DT_INVT, B.DT_CRTD,CAST(
case when
B.DT_INVT = '0000000' then B.DT_CRTD + 2000
when B.DT_INVT IS NULL then B.DT_CRTD + 2000
when B.DT_INVT = ' ' then B.DT_CRTD + 2000
ELSE B.DT_INVT + 2000
End as INT) As DueDate
FROM
(SELECT A.SITE_ID, A.NIIN
FROM DDCNENVR.QBO A
WHERE NOT (A.RIC IN ('SMS', 'S9W', 'S9D'))
and A.SITE_ID in ('HECL', 'HECN')
GROUP BY A.SITE_ID, A.NIIN) as t
inner join DDCNENVR.QBS B on t.NIIN = B.NIIN and t.SITE_ID = B.SITE_ID) as r
where r.DueDate between 2018206 and 2019273
GROUP BY r.SITE_ID)
The same code works for some dbs but fails in others.
After exporting the data without using the duedate between statement, the column types according to excel are as follows:
B.Dt_inv and B.dt_created are text
Duedate exports as number
In Db2 V11.1.0.0 and above you could use a function such as this to check if a value can be CAST to a DECIMAL.
CREATE OR REPLACE FUNCTION IS_DECIMAL(s VARCHAR(255))
RETURNS SMALLINT
LANGUAGE SQL
CONTAINS SQL
DETERMINISTIC
NO EXTERNAL ACTION
RETURN
REGEXP_LIKE(s, '^\s*[+-]?\s*((\d+\.?\d*)|(\d*\.?\d+))\s*$')
Use it like this
SELECT DT_INVT FROM DDCNENVR.QBS WHERE IS_DECIMAL(DT_INVT) = 0
It is not perfect as it does not allow all formats (e.g. 1e3 is castable to DECIMAL, but this function will say it is not), but it will catch e.g. 12 34 as not castable to DECIMAL whereas the TRANSLATE function would not.
It also does not check the length of the string to ensure that it is not more than 31 decimal digits.

Android Sqlite - Select the row which was inserted 1 hour before

Am working on Android Sqlite where I try to fetch the rows which are inserted 1 hour before.But its not returning any thing,I checked by cursor.count()
I tried with the following queries
String[] columns = new String[] { KEY_ID, KEY_CONTENT1, KEY_CONTENT2,
KEY_CONTENT3, KEY_CONTENT4, KEY_CONTENT5, KEY_CONTENT6};
cursor = sqLiteDatabase.query(MYDATABASE_TABLE, columns, KEY_CONTENT3 + "< " + "DATETIME('NOW', '-1 hours')", null, null, null, null);
AND another query
String selectRow = "select * FROM detail1 WHERE content3 < DATETIME('NOW', '-1 hours');";
Cursor cursor = sqLiteDatabase.execSQL(selectRow);
AND another query
String selectRow = "select * FROM detail1 WHERE content3 < DATETIME('NOW', '-1 hours');";
cursor = sqLiteDatabase.rawQuery(selectRow,null);
This Query Works for me
String selectRow = "select * FROM detail1 WHERE content3 > DATETIME('NOW', '-1 hours');";
Cursor cursor = sqLiteDatabase.execSQL(selectRow);
DATETIME('NOW', '-1 hours');"
This function returns time in this 2014-01-04,
and in data base 2014-01-04 10:24:21 have in this format. here only 2014 is getting compared not the complete date. better approch i would suggest go with epoch
try below query which will give you difference in terms of seconds
SELECT (strftime('%s','now')/60) - (strftime('%s',content3)/60);

How do I convert a number to a numeric, comma-separated formatted string?

Is there an easy way to convert a number (in my case an integer) to a comma separated nvarchar string?
For instance, if I had an int value of 1000000 stored in a field, how can I convert it to an nvarchar string with the outputted result of "1,000,000"?
I could easily write a function to do this but I wanted to be sure there wasn't an easier way involving a call to either CAST or CONVERT.
The reason you aren't finding easy examples for how to do this in T-SQL is that it is generally considered bad practice to implement formatting logic in SQL code. RDBMS's simply are not designed for presentation. While it is possible to do some limited formatting, it is almost always better to let the application or user interface handle formatting of this type.
But if you must (and sometimes we must!) use T-SQL, cast your int to money and convert it to varchar, like this:
select convert(varchar,cast(1234567 as money),1)
If you don't want the trailing decimals, do this:
select replace(convert(varchar,cast(1234567 as money),1), '.00','')
Good luck!
For SQL Server 2012, or later, an easier solution is to use FORMAT ()Documentation.
EG:
SELECT Format(1234567.8, '##,##0')
Results in: 1,234,568
Quick & dirty for int to nnn,nnn...
declare #i int = 123456789
select replace(convert(varchar(128), cast(#i as money), 1), '.00', '')
>> 123,456,789
Not sure it works in tsql, but some platforms have to_char():
test=#select to_char(131213211653.78, '9,999,999,999,999.99');
to_char
-----------------------
131,213,211,653.78
test=# select to_char(131213211653.78, '9G999G999G999G999D99');
to_char
-----------------------
131,213,211,653.78
test=# select to_char(485, 'RN');
to_char
-----------------
CDLXXXV
As the example suggests, the format's length needs to match that of the number for best results, so you might want to wrap it in a function (e.g. number_format()) if needed.
Converting to money works too, as point out by the other repliers.
test=# select substring(cast(cast(131213211653.78 as money) as varchar) from 2);
substring
--------------------
131,213,211,653.78
Although formatting belongs to the Presentation layer, SQL Server 2012 and above versions provide FORMAT() function which provides one of the quickest and easiest way to format output. Here are some tips & examples:
Syntax: Format( value, format [, culture ] )
Returns: Format function returns NVarchar string formatted with the specified format and with optional culture. (Returns NULL for invalid format-string.)
Note: The Format() function is consistent across CLR / all .NET languages and provides maximum flexibility to generate formatted output.
Following are few format types that can be achieved using this function:
Numeric/Currency formatting - 'C' for currency, 'N' number without currency symbol, 'x' for Hexa-decimals.
Date/Time formatting - 'd' short date, 'D' long date, 'f' short full date/time, 'F' long full date/time, 't' short time, 'T' long time, 'm' month+day, 'y' year+month.
Custom formatting - you can form your own-custom format using certain symbols/characters, such as dd, mm, yyyy etc. (for Dates). hash (#) currency symbols (£ $ etc.), comma(,) and so on. See examples below.
Examples:
Examples of Built-in Numeric/Currency Formats:
 select FORMAT(1500350.75, 'c', 'en-gb') --> £1,500,350.75
 select FORMAT(1500350.75, 'c', 'en-au') --> $1,500,350.75
 select FORMAT(1500350.75, 'c', 'en-in') --> ₹ 15,00,350.75
Examples of Built-in Date Formats:
 select FORMAT(getdate(), 'd', 'en-gb') --> 20/06/2017
 select FORMAT(getdate(), 'D', 'fr-fr') --> mardi 20 juin 2017
 select FORMAT(getdate(), 'F', 'en-us') --> Tuesday, June 20, 2017 10:41:39 PM
 select FORMAT(getdate(), 'T', 'en-gb') --> 22:42:29
Examples of Custom Formatting:
 select FORMAT(GETDATE(), 'ddd dd/MM/yyyy') --> Tue 20/06/2017
 select FORMAT(GETDATE(), 'dddd dd-MMM-yyyy') --> Tuesday 20-Jun-2017
 select FORMAT(GETDATE(), 'dd.MMMM.yyyy HH:mm:ss') --> 20.June.2017 22:47:20
 select FORMAT(123456789.75,'$#,#.00') --> $123,456,789.75
 select FORMAT(123456789.75,'£#,#.0') --> £123,456,789.8
See MSDN for more information on FORMAT() function.
For SQL Server 2008 or below convert the output to MONEY first then to VARCHAR (passing "1" for the 3rd argument of CONVERT() function to specify the "style" of output-format), e.g.:
 select CONVERT(VARCHAR, CONVERT(MONEY, 123456789.75), 1) --> 123,456,789.75
You really shouldn't be doing that in SQL - you should be formatting it in the middleware instead. But I recognize that sometimes there is an edge case that requires one to do such a thing.
This looks like it might have your answer:
How do I format a number with commas in T-SQL?
I looked at several of the options. Here are my two favorites, because I needed to round the value.
,DataSizeKB = replace(convert(varchar,Cast(Round(SUM(BigNbr / 0.128),0)as money),1), '.00','')
,DataSizeKB2 = format(Round(SUM(BigNbr / 0.128),0),'##,##0')
-----------------
--- below if the full script where I left DataSizeKB in both methods -----------
--- enjoy ---------
--- Hank Freeman : hfreeman#msn.com
-----------------------------------
--- Scritp to get rowcounts and Memory size of index and Primary Keys
SELECT
FileGroupName = DS.name
,FileGroupType =
CASE DS.[type]
WHEN 'FG' THEN 'Filegroup'
WHEN 'FD' THEN 'Filestream'
WHEN 'FX' THEN 'Memory-optimized'
WHEN 'PS' THEN 'Partition Scheme'
ELSE 'Unknown'
END
,SchemaName = SCH.name
,TableName = OBJ.name
,IndexType =
CASE IDX.[type]
WHEN 0 THEN 'Heap'
WHEN 1 THEN 'Clustered'
WHEN 2 THEN 'Nonclustered'
WHEN 3 THEN 'XML'
WHEN 4 THEN 'Spatial'
WHEN 5 THEN 'Clustered columnstore'
WHEN 6 THEN 'Nonclustered columnstore'
WHEN 7 THEN 'Nonclustered hash'
END
,IndexName = IDX.name
,RowCounts = replace(convert(varchar,Cast(p.rows as money),1), '.00','') --- MUST show for all types when no Primary key
--,( Case WHEN IDX.[type] IN (2,6,7) then 0 else p.rows end )as Rowcounts_T
,AllocationDesc = AU.type_desc
/*
,RowCounts = p.rows --- MUST show for all types when no Primary key
,TotalSizeKB2 = Cast(Round(SUM(AU.total_pages / 0.128),0)as int) -- 128 pages per megabyte
,UsedSizeKB = Cast(Round(SUM(AU.used_pages / 0.128),0)as int)
,DataSizeKB = Cast(Round(SUM(AU.data_pages / 0.128),0)as int)
--replace(convert(varchar,cast(1234567 as money),1), '.00','')
*/
,TotalSizeKB = replace(convert(varchar,Cast(Round(SUM(AU.total_pages / 0.128),0)as money),1), '.00','') -- 128 pages per megabyte
,UsedSizeKB = replace(convert(varchar,Cast(Round(SUM(AU.used_pages / 0.128),0)as money),1), '.00','')
,DataSizeKB = replace(convert(varchar,Cast(Round(SUM(AU.data_pages / 0.128),0)as money),1), '.00','')
,DataSizeKB2 = format(Round(SUM(AU.data_pages / 0.128),0),'##,##0')
,DataSizeKB3 = format(SUM(AU.data_pages / 0.128),'##,##0')
--SELECT Format(1234567.8, '##,##0.00')
---
,is_default = CONVERT(INT,DS.is_default)
,is_read_only = CONVERT(INT,DS.is_read_only)
FROM
sys.filegroups DS -- you could also use sys.data_spaces
LEFT JOIN sys.allocation_units AU ON DS.data_space_id = AU.data_space_id
LEFT JOIN sys.partitions PA
ON (AU.[type] IN (1,3) AND
AU.container_id = PA.hobt_id) OR
(AU.[type] = 2 AND
AU.container_id = PA.[partition_id])
LEFT JOIN sys.objects OBJ ON PA.[object_id] = OBJ.[object_id]
LEFT JOIN sys.schemas SCH ON OBJ.[schema_id] = SCH.[schema_id]
LEFT JOIN sys.indexes IDX
ON PA.[object_id] = IDX.[object_id] AND
PA.index_id = IDX.index_id
-----
INNER JOIN
sys.partitions p ON obj.object_id = p.OBJECT_ID AND IDX.index_id = p.index_id
WHERE
OBJ.type_desc = 'USER_TABLE' -- only include user tables
OR
DS.[type] = 'FD' -- or the filestream filegroup
GROUP BY
DS.name ,SCH.name ,OBJ.name ,IDX.[type] ,IDX.name ,DS.[type] ,DS.is_default ,DS.is_read_only -- discard different allocation units
,p.rows ,AU.type_desc ---
ORDER BY
DS.name ,SCH.name ,OBJ.name ,IDX.name
---
;
remove the commas with a replace and convert:
CONVERT(INT,REPLACE([varName],',',''))
where varName is the name of the variable that has numeric values in it with commas

How to generate better SQL from Linq2Sql query

I have the following query:
var data = from d in dc.GAMEs
where (d.GAMEDATE + d.GAMETIME.Value.TimeOfDay) >= DateTime.Now select d;
This generates some horendous looking SQL, looking something like this:
SELECT {...} WHERE DATEADD(ms, ((CONVERT(BigInt,((CONVERT(BigInt,DATEPART(HOUR, [t0].[GAMETIME]))) * 36000000000) + ((CONVERT(BigInt,DATEPART(MINUTE, [t0].[GAMETIME]))) * 600000000) + ((CONVERT(BigInt,DATEPART(SECOND, [t0].[GAMETIME]))) * 10000000) + ((CONVERT(BigInt,DATEPART(MILLISECOND, [t0].[GAMETIME]))) * 10000))) / 10000) % 86400000, CONVERT(DateTime,DATEADD(day, (CONVERT(BigInt,((CONVERT(BigInt,DATEPART(HOUR, [t0].[GAMETIME]))) * 36000000000) + ((CONVERT(BigInt,DATEPART(MINUTE, [t0].[GAMETIME]))) * 600000000) + ((CONVERT(BigInt,DATEPART(SECOND, [t0].[GAMETIME]))) * 10000000) + ((CONVERT(BigInt,DATEPART(MILLISECOND, [t0].[GAMETIME]))) * 10000))) / 864000000000, [t0].[GAMEDATE]))) >= #p0
What is the reason for this massive amount of SQL? And is there a better way to deal with it?
EDIT:
I have no control over the schema. It is what it is, and I have to deal with it.
If you can change the schema then the best way to deal with it is to use a single datetime2 column instead of separate date and time fields. Your current query will not be able to use an index.
Otherwise you could try rewriting the query as follows:
DateTime now = DateTime.Now;
var data = from d in dc.GAMEs
where (d.GAMEDATE > now.Date) ||
(d.GAMEDATE == now.Date && d.GAMETIME.Value.TimeOfDay >= now.TimeOfDay)
select d;
The SQL generated by this query might be slightly more readable and perhaps also more efficient. On the other hand, from a programmer's perspective it is more important that the source code is readable than the generated SQL is readable. If performance is not a concern you may want to leave your code as it is and just accept that the generated SQL is ugly and not worry about it.
As an alternative (since outermost OR is the bane of indexes)
DateTime now = DateTime.Now;
DateTime today = now.Date;
TimeSpan timeOfDay = now.TimeOfDay;
var data =
from d in dc.GAMEs
where d.GAMEDATE >= today
&& (d.GAMEDATE > today || d.GAMETIME.Value.TimeOfDay >= timeOfDay)
select d;