below is a query I am running to get all the accounts with a locate date not between the date of the transaction and transaction date - 60. When I run it, the query returns this rows that are incorrect. When looking into this problem I made sure all dates are of the same time (they are all defined as date, not timestamp).
Edit: I have also tried putting the dates in trunc() and to_date() to no avail.
Here are the values of the dates that I am receiving:
skip_locate :22-AUG-13
transaction_date :30-AUG-13
transaction_date - 60 :01-JUL-13
EDIT 2: For those wondering about the dates, and if they are really from 2013:
skip_locate :2013-08-22 00:00:00
transaction_date :2013-08-30 00:00:00
transaction_date - 60 :2013-07-01 00:00:00
Also as I was playing around, when I take away the NOT in the NOT BETWEEN I get no results. This is wrong due to the fact that skip_locate is in fact between the two dates.
Here is the query:
SELECT DISTINCT rl.complaint_date,
rl.complaint_amt,
rl.date_served1,
rl.date_served2,
rl.judgement_date,
rl.skip_locate,
lcc.bal_range_min,
lcc.bal_range_max,
lcc.cost_range_min,
lcc.cost_range_max,
lcc.court,
ah.ACCOUNT,
ah.transaction_code,
ah.transaction_date,
ah.transaction_date - 60 "t - 60",
ah.rule_id,
ah.amount,
ah.description,
r.state,
r.zip_code,
z.county
FROM racctrel r,
ziplist z,
legal_court_cost lcc,
racctlgl rl,
legal_transaction_review ah
WHERE substr(r.zip_code,1,5) = z.zip
AND r.state = lcc.state
AND REPLACE(lcc.county,' ','') = REPLACE(upper(z.county),' ','')
AND r.ACCOUNT = rl.ACCOUNT
AND r.ACCOUNT = ah.ACCOUNT
AND lcc.transaction_code = ah.transaction_code
AND lcc.transaction_code in (2,31)
AND lcc.end_date IS NULL
AND ah.batch_id = 257
and rl.skip_locate not between ah.transaction_date and ah.transaction_date - 60;
In a BETWEEN predicate you place the earliest value first and the latest one second, so the code should be:
... BETWEEN ah.transaction_date - 60 and ah.transaction_date
If you had two dates and were not sure which was earliest and which latest, you would:
... BETWEEN Least(date_1, date_2) and Greatest(date_1, date_2)
Related
In my requirement, I need to take the difference between date time by milliseconds. its most of the time receiving correctly, but in sometimes, it shows minus value.
in my table I'm storing EXPIREDDATE as follows, to update EXPIREDDATE time by 2 hours
UPDATE nd_user_encode_keys
SET EXPIREDDATE = SYSDATE + ( 1 / 1440 * 120) -- here 120 means 2 hours
and according to my SP, above query running before the below query.
SELECT (EXPIRYDATETIME - SYSDATE) * 24 * 60 * 60 * 1000 as EXPIRYDATETIMEINMILISECONDS
My problem is most of the time result is 7200000 , but somtimes it shows minus value like this -34932000 . what could be the reason for this issue. can someone please explain.
When you have A - B, then the result can be:
0, if A = B
a positive number, if A > B
a negative number, if A < B --> that is your case
Why is expirydatetime less than sysdate and is that a valid value, I wouldn't know, but you should as it is your database, you're storing values into that table.
According to update statement you posted, and regarding the fact that sysdate won't return the same value "right now" as it did "a few moments ago", then it depends on when you ran that update.
Therefore, I presume it is about time difference between update and select.
I have a requirement where I need to retrieve Row(s) 60 days prior to their "Retest Date" which is a column present in the table. I have also attached the screenshot and the field "Retest Date" is highlighted.
reagentlotid
reagentlotdesc
u_retest
RL-0000004
NULL
2021-09-30 17:00:00.00
RL-0000005
NULL
2021-09-29 04:21:00.00
RL-0000006
NULL
2021-09-29 04:22:00.00
RL-0000007
Y-T4
2021-08-28 05:56:00.00
RL-0000008
NULL
2021-09-30 05:56:00.00
RL-0000009
NULL
2021-09-28 04:23:00.00
This is what I was trying to do in SQL Server:
select r.reagentlotid, r.reagentlotdesc, r.u_retestdt
from reagentlot r
where u_retestdt = DATEADD(DD,60,GETDATE());
But, it didn't work. The above query returning 0 rows.
Could please someone help me with this query?
Use a range, if you want all data from the day 60 days hence:
select r.reagentlotid, r.reagentlotdesc, r.u_retestdt
from reagentlot r
where
u_retestdt >= CAST(DATEADD(DD,60,GETDATE())
AS DATE) AND
u_retestdt < CAST(DATEADD(DD,61,GETDATE()) AS DATE)
Dates are like numbers; the time is like a decimal part. 12:00:00 is half way through a day so it's like x.5 - SQLServer even lets you manipulate datetime types by adding fractions of days etc (adding 0.5 is adding 12h)
If you had a column of numbers like 1.1, 1.5. 2.4 and you want all the one-point-somethings you can't get any of them by saying score = 1; you say score >= 1 and score < 2
Generally, you should try to avoid manipulating table data in a query's WHERE clause because it usually makes indexes unusable: if you want "all numbers between 1 and 2", use a range; don't chop the decimal off the table data in order to compare it to 1. Same with dates; don't chop the time off - use a range:
--yes
WHERE score >= 1 and score < 2
--no
WHERE CAST(score as INTEGER) = 1
--yes
WHERE birthdatetime >= '1970-01-01' and birthdatetime < '1970-01-02'
--no
WHERE CAST(birthdatetime as DATE) = '1970-01-01'
Note that I am using a CAST to cut the time off in my recommendation to you, but that's to establish a pair of constants of "midnight on the day 60 days in the future" and "midnight on 61 days in the future" that will be used in the range check.
Follow the rule of thumb of "avoid calling functions on columns in a where clause" and generally, you'll be fine :)
Try something like this. -60 days may be the current or previous year. HTH
;with doy1 as (
select DATENAME(dayofyear, dateadd(day,-60,GetDate())) as doy
)
, doy2 as (
select case when doy > 0 then doy
when doy < 0 then 365 - doy end as doy
, case when doy > 0 then year(getdate())
when doy < 0 then year(getdate())-1 end as yr
from doy1
)
select r.reagentlotid
, r.reagentlotdesc
, cast(r.u_retestdt as date) as u_retestdt
from reagentlot r
inner join doy2 d on DATENAME(dayofyear, r.u_retestdt) = d.doy
where DATENAME(dayofyear, r.u_retestdt) = doy
and year(r.u_retestdt) = d.yr
It's been a while since I posted. I have an issue regarding date calculations.
I am trying to find the difference between two dates as in start time and finish time.
I have been able to find the difference in days so for instance if I have the dates:
start = 12/11/2014 12:05:05
finish = 13/11/2014 09:44:19
then the query gives me -0.90224537......
However, I need the answer in the form of hours, minutes, seconds for wage purposes. What is the best way of doing this?
My query so far is:
select
time_sheet.time_sheet_id,
time_sheet.start_date_time - time_sheet.finish_date_time,
employee_case.case, employee_case.employee
from
time_sheet
inner join
employee_case on time_sheet.employee_case = employee_case.employee_case_id
where
employee_case.case = 1;
P.S. I am using an Oracle database :)
date - date yields the difference in days. So you can use the standard time conversion to convert it to hours,minutes and seconds as below:
select
time_sheet.time_sheet_id,
(time_sheet.finish_date_time - time_sheet.start_date_time)||' days'||(time_sheet.finish_date_time - time_sheet.start_date_time)*24||' hours '||(time_sheet.finish_date_time - time_sheet.start_date_time)*24*60||' minutes '||(time_sheet.finish_date_time - time_sheet.start_date_time)*24*60*60||' seconds ' ,
employee_case.case, employee_case.employee
from
time_sheet
inner join
employee_case on time_sheet.employee_case = employee_case.employee_case_id
where
employee_case.case = 1;
Also, you would need finish_date_time as the minuend and start_date_time as the subtrahend to avoid negative values.
Thanks for the help toddlermenot but i have decided to go another way I have found. For anybody else who has the same issue I have done the following:
select
time_sheet.time_sheet_id,
to_number( to_char(to_date('1','J') +
(time_sheet.finish_date_time - time_sheet.start_date_time), 'J') - 1) days,
to_char(to_date('00:00:00','HH24:MI:SS') +
(time_sheet.finish_date_time - time_sheet.start_date_time), 'HH24:MI:SS') time,
employee_case.case, employee_case.employee
from
time_sheet
inner join
employee_case on time_sheet.employee_case = employee_case.employee_case_id
where
employee_case.case = 1;
This seems to do exactly what I need. It does the days in a serperate field to the hours minutes and seconds but for my purposes this is acceptable
I have the following SQL query:
SELECT t.trans_id, t.business_process_id, tsp.status, tsp.timestamp
FROM tran_stat_p tsp, tran t
WHERE t.trans_id = tsp.trans_id
AND tsp.timestamp BETWEEN '1-jan-2008' AND SYSDATE
AND t.business_process_id = 'ABC01'
It outputs data like this:
trans_ID business_process_id status timestamp
14444400 ABC01 F 6/5/2008 12:37:36 PM
14444400 ABC01 W 6/6/2008 1:37:36 PM
14444400 ABC01 S 6/7/2008 2:37:36 PM
14444400 ABC01 P 6/8/2008 3:37:36 PM
14444401 ABC01 F 6/5/2008 12:37:36 PM
14444401 ABC01 W 6/6/2008 1:37:36 PM
14444401 ABC01 S 6/7/2008 2:37:36 PM
14444401 ABC01 P 6/8/2008 3:37:36 PM
In addition to the above, I'd like to add a column which calculates the time difference (in days) between statuses W&F, S&W, P&S for every unique trans_id.
The idea is to figure out how long transactions are sitting in the various statuses before they are finally processed to status "P". The life cycle of a transaction is in the following order -> F -> W -> S -> P. Where F is the first status, and P is the final status.
Can anyone help? Thanks in advance.
The actual query would use LAG, which will give you a value from a prior row.
Your status codes won't sort as F -> W -> S -> P, which is why the query below has the big CASE statement for the LAG function's ORDER BY - it translates the status codes into a value that follows your transaction life cycle.
SELECT
t.trans_id,
t.business_process_id,
tsp.status,
tsp.timestamp,
tsp.timestamp - LAG(timestamp) OVER (
PARTITION BY tsp.trans_id
ORDER BY
CASE tsp.Status
WHEN 'F' THEN 1
WHEN 'W' THEN 2
WHEN 'S' THEN 3
WHEN 'P' THEN 4
END) AS DaysBetween
FROM tran t
INNER JOIN tran_stat_p tsp ON t.trans_id = tsp.trans_id
WHERE tsp.timestamp BETWEEN DATE '2008-01-01' AND SYSDATE
AND t.business_process_id = 'ABC01';
A couple more notes:
The query is untested. If you have trouble please post some sample data and I'll test it.
I used DATE '2008-01-08' to define Jnauary 1, 2008 because that's how Oracle (and ANSI) likes a date constant to look. When you use 1-jan-2008 you're relying on Oracle's default date format, and that's a session value which can be changed. If it's changed your query will stop working.
You can use LEAD to retrieve the next timestamp value and calculated the time left in every status (F, W and S) and TRUNC to calculated days between as an integer :
SELECT t."trans_ID", t."business_process_id", tsp."status", tsp."timestamp",
LEAD("timestamp", 1) OVER (
PARTITION BY tsp."trans_ID"
ORDER BY "timestamp") AS "next_timestamp",
trunc(LEAD("timestamp", 1) OVER (
PARTITION BY tsp."trans_ID"
ORDER BY "timestamp")) - trunc(tsp."timestamp") as "Days"
FROM tran t
INNER JOIN tran_stat_p tsp ON t."trans_ID" = tsp."trans_ID"
AND tsp."timestamp" BETWEEN '01-jan-2008 12:00:00 AM' AND SYSDATE
WHERE t."business_process_id" = 'ABC01'
See SQLFIDDLE : http://www.sqlfiddle.com/#!4/04633/49/0
Look into oracle window analytics.
http://www.orafaq.com/node/55
You'll want to do a diff of your current row date and the lag of that date.
Hope that makes sense.
I have a table defined in Oracle11g schema like this
Txn_summ_dec
=================
id
currentdate
resource_id
user_id
trans_id
eventdescptn
each resource has different event descriptions.
I give a date range (of maximum 1 month or less) and resource_id and I want to get distinct count of all users for the given resource id, group by currentdate, eventdescptn
So I have the following query
SELECT COUNT(DISTINCT(txn_summ_dec.user_id)) as dusers, currentDate, eventdescptn
FROM Txn_summ_dec
WHERE resource_id = 1
AND currentdate BETWEEN TO_DATE('2011-12-01', 'YYYY-MM-DD')
AND TO_DATE('2011-12-31', 'YYYY-MM-DD')
GROUP BY currentdate, eventdescptn
and it gives me rightly the result below
dusers currentdate eventdescptn
182 12/01/2011 00:00:00 Save
33 12/04/2011 00:00:00 Save
98 12/01/2011 00:00:00 Read
22 12/30/2011 00:00:00 Write
I want result in the following format: From the query
with the given date range is suppose 5th to 5th of a month (or less) I want results for all dates in the range for all eventdescptn of a resource. If there is no result for a particular date in the range, for a particular event descptn then it should still have that record in the resultset with a 'dusers' value = 0
so if a resource has 3 different eventdescptns (Save, Read, Write) and the date range is 5th to 30th of a month then there should be a total of 26X3 = 78 records in the resultset..
How do I write a query for that?
Also I will need to convert it to hibernate later.. but Sql to start with is fine
Thanks in advance
Check the accepted answer here:
generate days from date range
If I understand you correctly you don't necessarily have an event for every date in the range in your log. That answer gives you a way to materialize a list of dates in the range. If you can modify it to include 1 of each of those dates per event, you would just have to join back to the results you have already aggregated here and set the null dUsers to zero.
I haven't tried this, but I wonder if you could you do:
WITH the_query AS (
... your query here ...
)
SELECT dusers, currentdate, eventdescptn
FROM the_query
WHERE 0 != ( SELECT COUNT(*) FROM the_query )
UNION
SELECT 0, NULL, NULL
FROM the_query
WHERE 0 = ( SELECT COUNT(*) FROM the_query )