views:

1013

answers:

3

I have never used Informix before and I'm trying to write a query that will return records over the last 365 days.

Here is the query I have been trying to use:

Select * from Visit where vis_mod_dt between today-365 and today;

That returns no records even though I know that there is data for the last 365 days. I am guessing that the vis_mod_dt in not a true date column, although it displays as '12/31/1899' I have tried to cast this column using:

select * from visit where date(vis_mod_dt) between today-365 and today;

This still returns no data.

Any ideas?

+2  A: 

Informix DATE format

Be aware that the date 1899-12-31 corresponds to the internal date representation of zero (0). That is, internally, Informix stores DATE values in a 4-byte integer, and counts the number of days since 1899-12-31, so Day 1 was 1900-01-01 (and since it knows that 1900 was not a leap year, Day 60 was 1900-03-01).

That fact makes me worry about what is in your table. However, if the data in your table cannot be converted to a DATE upon request, normally you would get an error.

What is your table schema?

It would be sensible for you to establish the schema either using DB-Access and the Info/Tables option, or use DB-Schema:

dbschema -d dbase -t visit

The DB-Schema output is more suitable for adding to your question.

The query expressions using 'TODAY-365' and 'TODAY' should work fine - if there is data to select.

DBDATE environment variable

There is an environment variable, DBDATE, that you may need to set to get things to work - to convert from a string representation to dates. Since you are probably based in the UK (from your icon), then you may want and need to set the value of DBDATE to:

export DBDATE=DMY4/

This says that dates consist of the day, the month, a 4-digit year and the '/' is used as the preferred separator. You won't be surprised to learn that the presumed default value is usually 'MDY4/', for US format; I use 'Y4MD-' habitually, so I see DATE value the same as DATETIME YEAR TO DAY, which is the ISO 8601:2004 notation for a date. (It has many benefits: it is unambiguous, and naive sorting algorithms sort such dates into date order.) There's actually a lot of mechanism in the background in IDS (IBM Informix Dynamic Server - which, I assume, is the DBMS that you are using; there are some alternatives that are also Informix DBMS) such that strings with 2-digit dates will usually be converted correctly (but they are ambiguous and undesirable), and separators other than '/' will be recognized on input, but the slash will be used on 'output' (when converting DATE to string).


Information needed to improve the answer to this question - 1st Edition.

If what is here does not help, then I recommend editing your question to include:

  1. The table schema.
  2. A few (2-4) rows of data that you think should be selected but aren't.
  3. Platform and version information. It can help to have the version down to the level of detail of IDS 11.50.FC4W1; occasionally it matters. Most usually, the first three digits are what affect things, of course.

If your table is big (many columns), try to select the key columns (vis_mod_dt is by far the most important one). Ideally, you won't need any scroll bars in the display. Make sure you don't include any sensitive information.


Information needed to improve the answer to this question - 2nd Edition

I will help you if you pay attention to the questions I ask you. I cannot help you if you do not pay attention to the questions I ask. And please edit your question rather than adding information as an 'answer'.

  • What is the table schema? What is the output from:

    SELECT t.tabid, t.tabname, c.colno, c.colname, c.coltype, c.collength
      FROM "informix".systables AS t, "informix".syscolumns AS c
     WHERE t.tabid = c.tabid
       AND t.tabname = "visit"
     ORDER BY t.tabid, c.colno;
    
  • What do you get from:

    SELECT TODAY, TODAY-365 FROM "informix".systables WHERE tabid = 1;
    
  • Do you have the environment variable DBDATE set? If so, what is its value?

  • Do you have the environment variables CLIENT_LOCALE or DB_LOCALE set? If so, what are their values?
  • Which version of Informix are you using?
  • Which platform are you using it on?
  • Which language or tool are you using to run the query.

Note: if you cannot copy'n'paste the queries above, then you probably do not need to include the quoted '"informix".' attributes on the system catalog; however, as written, the queries will work on any extant Informix database - OnLine 5.x, SE 5.x or 7.x, IDS 7.x, XPS 8.x, IDS 9.x or 10.x or 11.x - and any mode of database (unlogged, logged, MODE ANSI). I'd use the JOIN notation except that some of the older versions don't support it - though you have to be on very old versions for that to be a problem.

Jonathan Leffler
There is a reason why some of the dates are from 1899, I believe the reason why was to fix a y2k issue.Are you saying that I do not need to cast this column even if it is not a true dateTime date type?So the expression 'TODAY-365' and 'TODAY' should return all data within 365 days of the current date, correct? How do I determine what the data type is?
Neil
@Neil: you might not need to cast it; IDS is pretty good at converting for you, especially strings to other types. Your `DATE(vis_mod_dt)` invocation is not strictly a cast (that would be `CAST(vis_mod_dt AS DATE)` or `vis_mod_dt::DATE`), but it is a conversion function that pre-dates the addition of explicit casting to IDS. The easiest way to determine the data type is to run DB-Schema, as suggested in my answer. The next easiest is to use DB-Access, select the database, then use the table menu and info option to find the column type. Please read the end of my answer for what else is needed.
Jonathan Leffler
This is a little confusing, because when I run the following, I get data:select count(*) from visit where vis_mod_dt between "10/01/2008" and "10/01/2009"
Neil
Thanks, when I run table schema select statement, I get ColType 7 for vis_mod_date, and according to IBM Informix documentation, thats a Date data-type.Next question, was the TODAY function introduced in a later version of Informix? In MS SQL Server when I run the following I get the current date:select GetDate()But when I run the following in Informix, I get a syntax error:Select TODAY or Select TODAY() or Select TODAY -365Thanks!
Neil
Actually, when I run SELECT TODAY, TODAY-365 FROM "informix".systables WHERE tabid = 1; I get two (expression) columns, 10/13/1981 and 10/13/1980
Neil
What system are you running on? Dammit - version numbers!!!!! It sounds like a broken PC running an archaic pre-Y2K version of Informix? TODAY has been in Informix SQL since 1985, and was in the pre-SQL product before that. But your system clock is not working as one would expect - or the Informix you are using is not adapting to the system clock. Is there are reason that you're reluctant to say what version? Like it is a decade or two out of support?
Jonathan Leffler
However, while TODAY is giving you a date in 1981, you are not going to be able to use it in your post-2000 queries. You are going to have to write out the dates you want longhand. Since current versions of IDS etc do not have problems with the system clock being set to 2009, I assume you are on something very old. But when you provide the platform and version information asked for yesterday, I can give you a better assessment of what to do next. Without that, I'm flying blind and getting annoyed about it.
Jonathan Leffler
A: 

This is a little confusing, because when I run the following, I get data:

select count(*) from visit where vis_mod_dt between "10/01/2008" and "10/01/2009"

Neil
A: 

how about unloading the table to ascii file, examine the unloaded vis_mod_dt values to see if they conform to DBDATE=MDY4 (mmddyyyy) format?.. if they do, ALTER vis_mod_dt to TYPE DATE if it's not a DATE column, then LOAD the unloaded table back in.

the: "BETWEEN today-365 AND today" part of your SELECT statement works for me in my apps.

Frank Computer