oracle sql query error while comparing date columns - sql

I have a following oracle sql query in which START_DATE is a number column and a_date is DATE type and the input value is also of type DATE. kindly let me know how to compare the date columns with the input date.
select a.id ,a.v ,b.id,b.v
from DATA a ,FDC b where a.START_DATE = to_date('11-DEC-10','YYYYMMDD')
and a.START_DATE = b.a_date and b.code = 'JFK'

select a.id ,a.v ,b.id,b.v
from DATA a ,FDC b where a.START_DATE LIKE TO_DATE('11-DEC-10','DD-MON-YY')
and a.START_DATE = b.a_date and b.code = 'JFK'
If you stored your START_DATE as Number like 'YYYYMMDD':
a.START_DATE=TO_NUMBER(TO_DATE('20101211','YYYYMMDD'))

It depends entirely on what format your number start_date column is stored in.
However, it would probably be easier if you used the predicate on the true date column, and joined using a format mask just once.
For example:
SELECT a.id,
a.v,
b.id,
b.v
FROM data a,
fdc b
WHERE b.a_date = to_date('11-DEC-2010','DD-MON-RRRR')
AND a.start_date = TO_NUMBER(TO_CHAR(b.a_date, 'DDMMRRRR'))
AND b.code = 'JFK'
Please note that the date format matches the format of the date you are comparing - b.a_date = to_date('11-DEC-2010','DD-MON-RRRR'). This query assumes that the a.start_date column is stored in the format DDMMRRRR. You would need to amend this for whichever format your date is stored in e.g. a.start_date = TO_NUMBER(TO_CHAR(b.a_date, 'J')) for a Julian date.
P.s. Why use a number to store a date?

select * from tbltlcrconfighistory where TO_DATE(STARTDATE,'dd-mon-yyyy') = TO_DATE('14-dec-2010','dd-mon-yyyy');

select * from tbltlcrconfighistory where STARTDATE = TO_DATE('14-dec-2010','dd-mon-yyyy');

Related

SQL query for extracting accounts whose last load date is not equal to today

I seem to have some issue in the query and need your help.
I have 2 tables:
1st table contains Bank account details - account number, status etc - bankacc
2nd table stores name of the statement and the load date on which the statement is imported - bankstm
I am trying to write a query that will populate only those bank accounts whose statement was not imported as of today date.
Date format in database - 2020-01-17 00:00:00.000
Code that i have tried:
SELECT b.bank_acc as Bank_Account, max(b.date_ld) as Load_Date from bankstm b
where b.date_ld < CAST(GETDATE() AS DATE) and
b.bank_acc in (select a.acc_no from bankacc a where a.in_use = 'Y' and a.analyse03 = '1517')
group by b.bank_acc
This code populates all the records from previous date whereas most of them statements loaded today.
I also attempted the code with '=' or '<>' or '>' based on the queries raised previously in stack overflow. But nothing seems to be giving me the correct result.
So finally i am raising it for experts to help me out.
You need to apply the date filter on the max.
I cast the max(b.date_ld) to date in case its datetime format
SELECT b.bank_acc as Bank_Account, max(b.date_ld) as Load_Date from bankstm b
where
b.bank_acc in (select a.acc_no from bankacc a where a.in_use = 'Y' and a.analyse03 = '1517')
group by b.bank_acc
having cast(max(b.date_ld) as date) < CAST(GETDATE() AS DATE)
You can modify your statement to use a not exists if your only criteria is that the record doesn't have a corresponding entry for today's date as a load date.
If the criteria is different, may require modification.
SELECT [b].[bank_acc] AS [bank_account]
, MAX([b].[date_ld]) AS [load_date]
FROM bankstm AS b
WHERE NOT EXISTS
(
SELECT 1
FROM [bankstm] AS [bb]
WHERE [b].[bank_acc] = [bb].[bank_acc] AND
TRY_CONVERT(DATE, [bb].[date_ld]) = TRY_CONVERT(DATE, GETDATE())
)
AND EXISTS
(
SELECT 1
FROM [bankacct] a
WHERE b.bank_acc = a.bank_acc and a.in_use = 'Y' and a.analyse03 = '1517'
)
GROUP BY b.bank_acc
;
first of all you can improve your query with join and avoid using sub query.
SELECT b.bank_acc as Bank_Account, max(b.date_ld) as Load_Date
FROM bankstm AS b
LEFT JOIN bankacc AS ba ON b.bank_acc = ba.acc_no
WHERE ba.in_use = 'Y'
AND ba.analyse03 = '1517'
GROUP BY b.bank_acc
HAVING CAST(MAX(b.date_ld) AS DATE) < CAST(GETDATE() AS DATE)
I would use not exists:
select ba.*
from bankacc ba
where ba.in_use = 'Y' and
ba.analyse03 = '1517' and
not exists (select 1
from bankstm bs
where bs.bank_acc = ba.acc_no and
bs.date_ld = convert(date, getdate())
);
For performance, you want indexes on bankacc(in_use, analyse03, acc_no) and bankstm(bank_acc, date_ld).

sql with group by and range of dates

I have a query which uses max aggregate function to calculate reset date for a particular selection date.There is a table vp_Accrual which have effectivedate field.selection date is passed to effectivedate field and based on that using Max function, reset date is calculated.This Query gives result only for a particular selection date.It calculate a reset date based on selection date passed.
I want to modify it so that it will give me reset date for a range of dates
Below Query gives Output for one person for the date 1st Jan as follow.
We need to modify Query so that it will give result for multiple selection date instead of only one selection date.
I tried by adding addition #enddate field as effectivedate between #selectiondate and #enddate.
But I guess tha approach is not correct.
I want to pass range of date, such as 1st jan to 4th Jan, and it should give Output for each date as below
[Image is added as Link as i dont have enough Repuation Point][https://i.stack.imgur.com/0HSX1.jpg]
Below is the Query used.
DECLARE #selectionDate datetime
SET #selectionDate = CONVERT(nvarchar(10), DATEADD(dd, 0, CAST('01/01/2017' AS datetime)), 101)
SELECT
e.personnum,
ac.name as Accrul_Code,
#selectionDate as Selection_DATE,
CASE
WHEN MAX(va.effectivedate) IS NULL THEN CAST('1/1/1753' AS datetime)
ELSE MAX(va.effectivedate)
END AS resetdate
FROM vp_employeev42 e WITH (NOLOCK)
INNER JOIN accrualprofile ap
ON e.accrualprflname = ap.name
INNER JOIN accrualprofilemm apm
ON apm.accrualprofileid = ap.accrualprofileid
INNER JOIN accrualrule ar
ON apm.accrualruleid = ar.accrualruleid
INNER JOIN accrualcode ac
ON ac.accrualcodeid = ar.accrualcodeid
LEFT OUTER JOIN vp_accrual va
ON va.accrualcodeid = ar.accrualcodeid
AND e.personid = va.personid
AND accrualtrantype IN (3, 11)
AND va.effectivedate <= #selectionDate
WHERE
ac.NAME IN ('FT PTO','LOC','EPT - 5','PT PTO','EPT')
AND va.DISQUALIFIEDSW != 1
and e.PERSONNUM='00152'
GROUP BY e.personnum,
ac.name
Please help me with this Query
Best I can make out, you want a Cartesian join on a fake date table that will cause your results to repeat themselves over and over, but for a different set of dates each time
Something like this:
DECLARE #selectionDate datetime
DECLARE #endDate datetime
SET #selectionDate = DATEFROMPARTS(2017,1,1)
SET #endDate = DATEFROMPARTS(2017,5,1)
WITH dates ( IncDate ) AS (
SELECT #selectionDate UNION ALL
SELECT DATEADD(month,1,IncDate) FROM dates WHERE Incdate <= #endDate )
SELECT
e.personnum,
ac.name as Accrul_Code,
IncDate as Selection_DATE,
MAX(COALESCE(effectivedate, CAST('1/1/1753' AS datetime)) AS resetdate
FROM vp_employeev42 e WITH (NOLOCK)
INNER JOIN accrualprofile ap
ON e.accrualprflname = ap.name
INNER JOIN accrualprofilemm apm
ON apm.accrualprofileid = ap.accrualprofileid
INNER JOIN accrualrule ar
ON apm.accrualruleid = ar.accrualruleid
INNER JOIN accrualcode ac
ON ac.accrualcodeid = ar.accrualcodeid
CROSS JOIN dates
LEFT OUTER JOIN vp_accrual va
ON va.accrualcodeid = ar.accrualcodeid
AND e.personid = va.personid
AND accrualtrantype IN (3, 11)
AND effectivedate <= IncDate
WHERE
ac.NAME IN ('FT PTO','LOC','EPT - 5','PT PTO','EPT')
AND va.DISQUALIFIEDSW != 1
and e.PERSONNUM='00152'
GROUP BY e.personnum,
ac.name,
IncDate
A few cautions though:
This query cannot generate the results you posted, but neither can yours. There's no logic at all to your example results, where your reset date is the max date that is less than the selection date but your first of February selection date somehow chooses the tenth of Jan, yet your first of march selection date chooses the eleventh of Jan.
This is totally untested; you provided no sample data, only an image of the results, and I post from an iPad, so generating test data would be incredibly laborious, typing it all in
You mix up your dates as varchar and datetime. Please be more diligent in keeping these data types separate. Always work with dates as dates, not strings. Never store dates as string. Never rely on implicit conversions between date and string
DATEFROMPARTS came along in sqlserver 2012 I think, if your sql is older than this, use convert with a format string to turn your string into a date.. do not declare selectiondate as a varchar!

Oracle SQL Groupby and SUM

I have the following query that groups every tender id and description and shows its total Sum:
3020 American Express 20
1000 Cash - primary currency 9903.25
3120 House Card 2605.56
4070 Purchase Order 668.25
3000 Visa 26005.19
SELECT B.TENDER_TYPE_ID, A.TENDER_TYPE_DESC, SUM (B.TENDER_AMT)
FROM POS_TENDER_TYPE_HEAD A, SA_TRAN_TENDER B, SA_TRAN_HEAD C
WHERE A.TENDER_TYPE_ID = B.TENDER_TYPE_ID AND B.TRAN_SEQ_NO = C.TRAN_SEQ_NO
GROUP BY B.TENDER_TYPE_ID, A.TENDER_TYPE_DESC
In the table C (SA_TRAN_HEAD), there is a field of TRAN_DATETIME.
I want the query to return the results falling between an interval of dates but do not want the date to appear in the query columns.
What could I do to achieve this ?
Just add the desired date range to the WHERE clause:
SELECT B.TENDER_TYPE_ID,
A.TENDER_TYPE_DESC,
SUM (B.TENDER_AMT)
FROM POS_TENDER_TYPE_HEAD A,
SA_TRAN_TENDER B,
SA_TRAN_HEAD C
WHERE A.TENDER_TYPE_ID = B.TENDER_TYPE_ID AND
B.TRAN_SEQ_NO = C.TRAN_SEQ_NO AND
C.TRAN_DATETIME BETWEEN TO_DATE('01-JAN-2015', 'DD-MON-YYYY')
AND TO_DATE('31-MAR-2015', 'DD-MON-YYYY')
GROUP BY B.TENDER_TYPE_ID,
A.TENDER_TYPE_DESC
I also suggest you get used to using ANSI join syntax, as it makes the joins much clearer and is more transportable (particularly for outer joins). The following should be equivalent:
SELECT B.TENDER_TYPE_ID,
A.TENDER_TYPE_DESC,
SUM (B.TENDER_AMT)
FROM POS_TENDER_TYPE_HEAD A
INNER JOIN SA_TRAN_TENDER B
ON B.TENDER_TYPE_ID = A.TENDER_TYPE_ID
INNER JOIN SA_TRAN_HEAD C
ON C.TRAN_SEQ_NO = B.TRAN_SEQ_NO
WHERE C.TRAN_DATETIME BETWEEN TO_DATE('01-JAN-2015 00:00:00', 'DD-MON-YYYY HH24:MI:SS')
AND TO_DATE('31-MAR-2015 23:59:59', 'DD-MON-YYYY HH24:MI:SS')
GROUP BY B.TENDER_TYPE_ID,
A.TENDER_TYPE_DESC
This makes it clear what the join criteria are, as opposed to the filter criteria.

how to join 2 query into one in EXCEL ORACLE CONNECTION

I have 2 query.
I am trying to join them so I just write export from one instead of manually joining them in excel.
(SELECT
b.OUT_NO,
a.ACCNO,
a.BILL_ACCNO,
a.NAME,
a.HOUSE_NO,
a.STREET,
a.HOUSE_NO2,
a.ZIP,
a.ID,
b.TIME_STAMP,
b.REST_DATE,
c.RESTORED_TIME,
b.OUT_CMNT
FROM brook.account a,
brook.problem b,
brook.history c
WHERE c.OUT_NO = b.OUT_NO
AND a.ID = c.ID
AND ( (a.NAME Is Not Null)
AND (a.DISC Is Null)
AND (b.TIME_STAMP>?)
AND (c.RESTORED_TIME<?))
)
and
(SELECT
b.OUT_NO,
a.ACCNO,
a.BILL_ACCNO,
a.NAME,
a.HOUSE_NO,
a.STREET,
a.HOUSE_NO2,
a.ZIP,
a.ID,
b.TIME_STAMP,
b.REST_DATE,
c.RESTORED_TIME,
b.OUT_CMNT
FROM brook.account a,
brook.problem b,
brook.history c
WHERE c.OUTAGE_NO = b.OUTAGE_NO
AND a.ID = c.ID
AND ( (a.NAME Is Not Null)
AND (a.DISC Is Null)
AND (b.TIME_STAMP > ? And b.TIME_STAMP < ?)
AND (c.RESTORED_TIME > ? And c.RESTORED_TIME < ?)
)
)
How can I join these 2? into 1, I tried UNION ALL but I get ora-01847 day of month must be between 1 and last day of month ERROR.
? are the parameter, it is linked to cells on spreadsheet.
format of excel data parameter. 11/04/2013 00:00:00
Thanks
Error is about a date format, not about union.
If you pass cell values as string parameters Oracle tries to convert it to dates to comapre with columns of date or timestamp values in table columns. To do this conversion Oracle uses it's internal default date representation format wich is not mm/dd/yyyy hh24:mi:ss in your case.
There are 2 possibilities to fix a situation:
Pass parameters with date type to query and convert values to dates before passing it to Oracle. Check examples on MSDN and description of CreateParameter and Parameters.Append methods.
Convert values to dates in query with to_date Oracle function.
Change conditions in query from
AND (b.TIME_STAMP>?)
AND (c.RESTORED_TIME<?))
and
AND (b.TIME_STAMP > ? And b.TIME_STAMP < ?)
AND (c.RESTORED_TIME > ? And c.RESTORED_TIME < ?)
to
AND (b.TIME_STAMP > to_date(?,'mm/dd/yyyy hh24:mi:ss') )
AND (c.RESTORED_TIME < to_date(?,'mm/dd/yyyy hh24:mi:ss') ))
and
AND (
b.TIME_STAMP > to_date(?,'mm/dd/yyyy hh24:mi:ss')
And
b.TIME_STAMP < to_date(?,'mm/dd/yyyy hh24:mi:ss')
)
AND (
c.RESTORED_TIME > to_date(?,'mm/dd/yyyy hh24:mi:ss')
And
c.RESTORED_TIME < to_date(?,'mm/dd/yyyy hh24:mi:ss')
)

How to convert a DATE column to DATETIME in SQL, querying an Access database?

I have a SQL query to where I need to convert a DATE column to DATETIME from an Access database.
The columns to be converted are:
CHECKINOUT.CHECKTIME
CHECKINOUT.DefaultIn
CHECKINOUT.DefaultOut
This is my query:
SELECT
USERINFO.NAME, USERINFO.EmployeeCode, CHECKINOUT.CHECKTYPE,
CHECKINOUT.DefaultIn, CHECKINOUT.DefaultOut, CHECKINOUT.DefaultBreckIn,
CHECKINOUT.DefaultBreakOut, CHECKINOUT.CHECKTIME, USERINFO.TITLE
FROM
(CHECKINOUT
INNER JOIN USERINFO ON CHECKINOUT.USERID = USERINFO.USERID)
WHERE
(CHECKINOUT.CHECKTIME >= ?)
AND (CHECKINOUT.CHECKTIME <= ?)
AND (CHECKINOUT.USERID = ? OR ? = - 1)
AND (CHECKINOUT.DefaultIn <= CHECKINOUT.CHECKTIME OR
CHECKINOUT.DefaultOut >= CHECKINOUT.CHECKTIME )
What's the best way?
Thanks
You have to use the Format function in your query, example:
Format([datetime column],'dd-mm-yyyy # hh:nn:ss AM/PM')
and in your SQL:
SELECT Format([CHECKINOUT.CHECKTIME],'dd-mm-yyyy # hh:nn:ss AM/PM') AS DT_CHECKTIME ...