Oracle date column showing the wrong value - sql

I'm trying to identify a problem in a date colum in my table.
The database is Oracle 11g.
The situation is:
When I run the following query:
select to_char(data_val, 'DD/MM/YYYY'), a.data_val from material a order by a.data_val asc;
the five first lines of the result are:
00/00/0000 | 29/06/5585 00:00:00
00/00/0000 | 29/06/5585 00:00:00
00/00/0000 | 29/06/5585 00:00:00
11/11/1111 | 11/11/1111 00:00:00
01/01/1500 | 01/01/1500 00:00:00
the question is:
Why the to_char function of the first three lines returns a different value of date (00/00/0000)?
And why the date 29/06/5585 is the first result of a ASC date order by? It'll be right using: order by data_val DESC, will not?

We've encountered the same problem. I can confirm that the "date" column is indeed the DATE type.
The date in question is 01-May-2014, so it's most likely not related to the big year number in the original post. And when you perform some calculation with the date, the problem is fixed, i.e. TO_CHAR(datum) would be all zeros, TO_CHAR(datum + 1) would be as expected, and even TO_CHAR(datum +1 -1) would be correct. (TO_CHAR(datum+0) doesn't help :))
Based on the DUMP value it seems that the problem is that we've somehow managed to store 31-Apr-2014 rather than 01-May-2014 (investigating now how that was possible; Informatica + Oracle 11.2, I believe).

Related

traversing the records in sql

I would like to get the output for the over lapping date records
> Data: Id Open_date Closed_Date
> 1 2016-01-01 2017-01-01
**> 1 2016-12-31 2018-21-01
> 1 2016-01-01 2018-01-01**
> 2 2017-01-01 2018-02-02
Here, you see the second & 3rd records are starting with date than the closed_Date of their previous records. Here i need to identify those type of records
As you question is not much clear, I am assuming that you are looking for min of open date and max of close date.
If this is not the requirement edit the question to provide more details.
select id, min(Open_date), max(Closed_Date)
from table
group by id
Looks like you want to normalize a Slowly Changing Dimension Type 2. Of course the best way to handle them would be using Temporal tables using either Teradata or ANSI syntax.
There's a nice syntax in Teradata to get your expected result based on the Period data type, but it's imple to cast your begin/end dates to a period:
SELECT id,
-- split the period back into seperate dates
Begin(pd) AS Open_date,
End(pd) AS Closed_Date
FROM
(
SELECT NORMALIZE -- magic keyword :-)
id, PERIOD(Open_date, Closed_Date) AS pd
FROM tab
) AS dt

SQL minimum date value after today's date Now()

I am writing a query and am having trouble filtering data as I would like. In the table, there is a date field and an ItemCode field. I would like to return one record per ItemCode with the earliest date that is after today.
If today is 6/6/2017 and my data looks like:
ItemCode Date
1 6/1/2017
1 6/7/2017
1 6/10/2017
2 6/2/2017
2 6/8/2017
2 6/15/2017
I would want the result to be
ItemCode Date
1 6/7/2017
2 6/8/2017
My query so far is:
SELECT PO_PurchaseOrderDetail.ItemCode, Min(PO_PurchaseOrderDetail.RequiredDate) AS NextPO
FROM PO_PurchaseOrderDetail
GROUP BY PO_PurchaseOrderDetail.ItemCode
HAVING (((Min(PO_PurchaseOrderDetail.RequiredDate))>=Now()));
The problem is that the Min function fires first and grabs the earliest dates per ItemCode, which are before today. Then the >=Now() is evaluated and because the min dates are before today, the query returns nothing.
I've tried putting the >=Now() inside the min function in the HAVING part of the query but it does not change the result.
My structure is wrong and I would appreciate any advice. Thanks!
I would approach like this for standard SQL, Access approach may vary
select PO_PurchaseOrderDetail.ItemCode,
min(PO_PurchaseOrderDetail.RequiredDate) as NextPO
from PO_PurchaseOrderDetail
where PO_PurchaseOrderDetail.RequiredDate >= Now()
group by PO_PurchaseOrderDetail.ItemCode;
Put the date condition in the where clause (not the having clause):
select ItemCode, min(Date) as NextPO
from PO_PurchaseOrderDetail
where Date > '6/6/2017'
group by ItemCode

Query sql pivot on date transformation

I have a table called LAB and it has these important field:
DATA, CODE, STRUTT.
DATA contains dates, code string and strutt integer as well
What I need is to query this table and get back something like:
-----------------------
| DAYS | YEAR | YEAR2 |
-----------------------
| | STRUTT |
-----------------------
| | | |
They suggest me to use pivot. But I don't know how to group years.
My first try was:
SELECT * FROM
(
SELECT STRUTT, CODe, DATA
FROM LAB
WHERE DATA >= DATE '2016-05-01' AND DATA <= DATE '2016-05-31'
)
PIVOT
(
count(DISTINCT CODE)
FOR STRUTT IN (21,22,23,24,25,26)
)
This is a start for my use of Pivot. But then i tried to change the for statement and put:
FOR DATA IN ('2016-05-01','2016-05-21')
but this gave me errors. Some ideas for solve the entire problem? Or at least to solve the last one of dates? SOLVED BUT NOT NEEDED AT THE END TO SOLVE THE PROBLEM
It looks like you are using Oracle. I might suggest trying:
FOR DATA IN (DATE '2016-05-01', DATE '2016-05-21')
Otherwise, the string values are interpreted as strings, not dates.
I solve the problem by having a look somewhere... I still don't know which version of Oracle I'm using. By the way this work for me:
select strutt
, to_char(data,'dd-MON') AS dayMonth
, count(DISTINCT (case extract(year from data) when 2015 then code end)) numutenze_2015
, count(DISTINCT (case extract(year from data) when 2016 then code end)) numutenze_2016
from lab
where data >= DATE '2015-01-01' and data <= DATE '2016-06-08'
group by strutt, to_char(data,'dd-MON')
order by strutt, to_char(data,'dd-MON') asc
The only problem I have, I don't know how to order the Dates... it start from April, then August... ecc

Sort by / Order by time stored in database "00:00 - 23:00"

I'm trying to figure out an sql query that would allow me to sort data ascending order depending on what time is sorted in appointment_time column, it has values like "00:00" - "23:00"
In my head it looks like this:
SELECT * FROM myTable ORDER BY appointment_time ASC
But I don't know how to make it understand that 00:00 is lower value than 00:01 for example and so on.
They will sort fine as your query is written, easiest thing is to just give it a whirl and see what happens:
SELECT *
FROM myTable
ORDER BY appointment_time ASC
Demo: SQL Fiddle
Alphanumeric ordering has no problem with numbers stored in strings so long as they are zero padded, as is the case with your times.
But I don't know how to make it understand that 00:00 is lower value than 00:01
If all you have is a time then an alphabetical sort should work just fine. If you want to convert to a DateTime you can use CONVERT:
select CONVERT(DATETIME, appointment_time , 108)
If you store from_time and to_time as DATETIME (in two separate columns), the sorting will be done correctly by the DB.
It will also take into consideration the date part as well, i.e. sort 1 Jan 2014 23:00 before 31 Dec 2013 23:30. If you really aren't interested in the date, use a dummy date for all entries and just use the time part of the column.

Group by in t-sql not displaying single result

See the image below. I have a table, tbl_AccountTransaction in which I have 10 rows. The lower most table having columsn AccountTransactionId, AgreementId an so on. Now what i want is to get a single row, that is sum of all amount of the agreement id. Say here I have agreement id =23 but when I ran my query its giving me two rows instead of single column, since there is nano or microsecond difference in between the time of insertion.
So i need a way that will give me row 1550 | 23 | 2011-03-21
Update
I have update my query to this
SELECT Sum(Amount) as Amount,AgreementID, StatementDate
FROM tbl_AccountTranscation
Where TranscationDate is null
GROUP BY AgreementID,Convert(date,StatementDate,101)
but still getting the same error
Msg 8120, Level 16, State 1, Line 1
Column 'tbl_AccountTranscation.StatementDate' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Your group by clause is in error
group by agreementid, convert(date,statementdate,101)
This makes it group by the date (without time) of the statementdate column. Whereas the original is grouping by the statementdate (including time) then for each row of the output, applying the stripping of time information.
To be clear, you weren't supposed to change the SELECT clause
SELECT Sum(Amount) as Amount,AgreementID, Convert(date,StatementDate,101)
FROM tbl_AccountTranscation
Where TranscationDate is null
GROUP BY AgreementID,Convert(date,StatementDate,101)
Because you have a Group By StatementDate.
In your example you have 2 StatementDates:
2011-03-21 14:38:59.470
2011-03-21 14:38:59.487
Change your query in the Group by section instead of StatementDate to be:
Convert(Date, StatementDate, 101)
Have you tried to
Group by (Convert(date,...)
instead of the StatementDate
You are close. You need to combine your two approaches. This should do it:
SELECT Sum(Amount) as Amount,AgreementID, Convert(date,StatementDate,101)
FROM tbl_AccountTranscation
Where TranscationDate is null
GROUP BY AgreementID,Convert(date,StatementDate,101)
If you never need the time, the perhaps you need to change the datatype, so you don't have to do alot of unnecessary converting in most queries. SQL Server 2008 has a date datatype that doesn't include the time. In earlier versions you could add an additional date column that is automatically generated to strip out the time companent so all the dates are like the format of '2011-01-01 00:00:00:000' then you can do date comparisons directly having only had to do the conversion once. This would allow you to have both the actual datetime and just the date.
You should group by DATEPART(..., StatementDate)
Ref: http://msdn.microsoft.com/en-us/library/ms174420.aspx