25.01.2014 Views

Common SQL Questions - International Informix Users Group

Common SQL Questions - International Informix Users Group

Common SQL Questions - International Informix Users Group

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

L04<br />

<strong>Common</strong> <strong>SQL</strong><br />

<strong>Questions</strong><br />

Why and How-to<br />

Tuesday, May 9, 2006 • 08:30a.m. – 09:40 a.m.<br />

There are a few questions that come up time and time again. Why do certain<br />

<strong>SQL</strong> statements behave the way they do, and how do I get a particular set of<br />

results? This presentation will cover some of the most frequently asked <strong>SQL</strong>related<br />

questions. We'll also discuss how to find out how others have found<br />

answers and solutions to similar problems.<br />

1


Agenda<br />

• Using DATE and DATETIME in calculations<br />

• Putting limits and order on rows returned<br />

• User-Defined Routines and SPL considerations<br />

• Explain plan query estimates<br />

• Replace newlines in text<br />

2<br />

2


How can I manipulate dates and<br />

times?<br />

• <strong>Common</strong> problems with date and time<br />

manipulation are due to misunderstandings about<br />

the data types.<br />

• There are a number of built-in functions that will<br />

help.<br />

3<br />

3


Date and Time Data types<br />

• DATE (mm/dd/yyyy)<br />

• DATETIME (yyyy-mm-dd hh:mm:ss.nnnnn)<br />

• INTERVAL (year-month OR day-time)<br />

4<br />

-The DBDATE and GL_DATE environment variables may be used to change<br />

the default DATE format.<br />

-The default precision for DATETIME fraction is 3 digits; may use as many as<br />

5.<br />

-Can not combine the two INTERVAL classes.<br />

4


DATE<br />

• Stored internally as an integer<br />

• Value is equal to the number of days since<br />

December 31, 1899<br />

DATE(1) = 01/01/1900<br />

DATE(38717) = 01/01/2006<br />

5<br />

The DATE function will be described in a few slides.<br />

5


DATETIME<br />

• Stores an “instant in time” as a date and time of<br />

day<br />

• Precision defined from a year to a fraction of a<br />

second<br />

DATETIME YEAR TO FRACTION(3)<br />

06-02-28 11:03:27.002<br />

<br />

Year Day Minute Fraction<br />

Month Hour Second<br />

6<br />

Note the format of the DATETIME example.<br />

-Hyphen is used between the date portion of the DATETIME<br />

-Space separates date from time<br />

-Colon is used between hour and minutes, and minutes and seconds<br />

-Decimal point separates the fraction from seconds<br />

6


INTERVAL<br />

• Represents a span of time - independent of any<br />

actual date<br />

• Year-Month intervals<br />

YEAR, MONTH<br />

• Day-Time intervals<br />

DAY, HOUR, MINUTE, SECOND, FRACTION<br />

7<br />

Because the interval is independent of a specific date, you cannot combine the<br />

two classes of intervals. As the number of days in a given month (and some<br />

years) varies, a single interval value cannot combine months and days.<br />

7


Date/Time Keywords<br />

• TODAY<br />

Returns the system date as a DATE value<br />

e.g. select TODAY from systables where tabid = 1;<br />

returns: 02/17/2006<br />

• CURRENT<br />

Returns a DATETIME value representing the<br />

current moment<br />

e.g. select CURRENT from systables where tabid = 1;<br />

returns: 2006-02-17 17:37:12.000<br />

8<br />

8


Date/Time Built-in Functions<br />

• DATE<br />

• DAY<br />

• MONTH<br />

• YEAR<br />

• MDY<br />

• EXTEND<br />

• WEEKDAY<br />

9<br />

9


DATE<br />

• Returns a date value that corresponds to a nondate<br />

expression<br />

• DATE(non-date expression)<br />

SELECT * FROM orders<br />

WHERE order_date > DATE(‘05/01/2006’)<br />

10<br />

See the examples at the beginning of this section where an INTEGER is used<br />

as an argument.<br />

10


Example with DATE<br />

• Question: I am trying to select records using a<br />

datetime field. I only care about the date part<br />

when doing my select. Can I select the whole day<br />

record without having to account for all the time<br />

possibilites within a given day?<br />

SELECT * FROM tablename<br />

WHERE DATE(datetime_col) = TODAY - 1;<br />

11<br />

11


DAY<br />

• Returns an integer representing the day of the<br />

month<br />

• DAY(date/datetime expression)<br />

SELECT * FROM orders<br />

WHERE DAY(order_date) > 15<br />

12<br />

Search for orders that were placed after the 15th day of any month.<br />

12


MONTH<br />

• Returns an integer representing the month portion<br />

of a DATE or DATETIME<br />

• MONTH(date/datetime expression)<br />

SELECT * FROM cust_calls<br />

WHERE MONTH(call_dtime) = 12<br />

13<br />

Select all from cust_calls where the call was recorded in December (12th<br />

month).<br />

13


YEAR<br />

• Returns a four-digit integer that represents the<br />

year<br />

• YEAR(date/datetime expression)<br />

SELECT * FROM orders<br />

WHERE YEAR(paid_date) = YEAR(TODAY)<br />

14<br />

Select all orders that were paid in the current year.<br />

14


MDY<br />

• Returns a DATE value with three expressions that<br />

evaluate to integers that represent the month, day,<br />

and year<br />

• MDY(month,day,year)<br />

UPDATE orders SET ship_date =<br />

MDY(MONTH(TODAY) + 1, 1, YEAR(TODAY))<br />

WHERE order_date = TODAY<br />

15<br />

Update the orders table, setting the ship date to the first day of next month<br />

(based on today’s date) for all orders placed today.<br />

15


EXTEND<br />

• Adjusts the precision of a DATETIME or DATE<br />

value<br />

• EXTEND(date/datetime expression, first TO last)<br />

SELECT EXTEND(TODAY, YEAR TO MINUTE)<br />

FROM systables WHERE tabid = 1;<br />

Returns: 2006-02-17 00:00<br />

16<br />

We are extending the precision of TODAY so that it includes hours and<br />

minutes.<br />

16


Example with EXTEND<br />

• Question: I am trying to select records using a<br />

datetime field. I only care about the date part<br />

when doing my select. Can I select the whole day<br />

record without having to account for all the time<br />

possibilites within a given day?<br />

SELECT * FROM tablename<br />

WHERE EXTEND(datetime_col, year to day) = TODAY - 1;<br />

17<br />

Note - same question as seen on slide 11, but with a different solution.<br />

17


Same question - another way<br />

SELECT * FROM tablename<br />

WHERE EXTEND(datetime_col, year to day) = “2006-05-01”;<br />

18<br />

Note: If you are going to enter a string to represent the day that you are<br />

looking for (May 1, 2006 in this example), be sure to format that string<br />

properly for the DATETIME datatype.<br />

18


WEEKDAY<br />

• Returns an integer that represents a day of the<br />

week (0 = Sunday, 6 = Saturday)<br />

• WEEKDAY(date/datetime expression)<br />

SELECT * FROM cust_calls<br />

WHERE WEEKDAY(call_dtime) = 5<br />

19<br />

Find all customer calls that came in on a Friday.<br />

19


UNITS of time<br />

• YEAR, MONTH, DAY, HOUR, MINUTE, SECOND,<br />

FRACTION<br />

SELECT * FROM call_log<br />

WHERE call_date >= (TODAY - 7 UNITS DAY)<br />

20<br />

You can not add, for example, MINUTE UNITS to a DATE -- the UNITS of<br />

time must be compatible with the datatype.<br />

Attempting to add minutes to a date produced the following error (-1266):<br />

Intervals or datetimes are incompatible for the operation.<br />

20


Adding and Subtracting time<br />

• Why do I get an error when I subtract a month?<br />

Example:<br />

Let’s say today is 03/30/2005<br />

Today - 1 UNITS MONTH = ERROR<br />

02/30/2005 is an invalid date!<br />

21<br />

21


How do I get the first day of the<br />

previous or next month?<br />

SELECT order_num, order_date,<br />

DATE(EXTEND(order_date, YEAR TO MONTH)<br />

- 1 UNITS MONTH) AS prev_month,<br />

DATE(EXTEND(order_date, YEAR TO MONTH)<br />

+ 1 UNITS MONTH) AS next_month<br />

FROM orders<br />

22<br />

In this example, we are adjusting the precision of the order date so that we are<br />

taking just the year and month and using that as an argument to the DATE<br />

function. In addition, we are either subtracting or adding one month to the<br />

result of the EXTEND. The final result will be to give us the order number,<br />

the original order date, the first of the month prior to the order date, and the<br />

first of the month following the order date.<br />

22


How do I get the last day of the<br />

current month?<br />

SELECT (CURRENT - (DAY(CURRENT)) UNITS DAY<br />

+ 1 UNITS DAY) + 1 UNITS MONTH - 1 UNITS DAY<br />

FROM systables WHERE tabid = 1;<br />

Also works:<br />

SELECT (CURRENT - (DAY(CURRENT) - 1) UNITS DAY)<br />

+ 1 UNITS MONTH - 1 UNITS DAY<br />

FROM systables WHERE tabid = 1;<br />

23<br />

Once you’ve worked out how to get the last day of the current month, it<br />

shouldn’t be too difficult to work out how to get the last day or the next or<br />

previous month.<br />

Although this example used CURRENT (DATETIME data type), handling a<br />

DATE data type is another option - as is using MDY and EXTEND and ….<br />

Remember: TMTOWTDI (There’s more than one way to do it).<br />

SELECT MDY(MONTH(TODAY) + 1, 1, YEAR(TODAY)) - 1<br />

MDY returns a DATE - get first day of next month, and subtract a day<br />

(remember a DATE is stored as an integer - don’t need to include the UNITS<br />

keyword).<br />

23


I’m still having trouble with<br />

dates…<br />

• Much of what you will need to do has already been<br />

done before.<br />

• A few more examples…<br />

24<br />

If you are unable to work it out through testing, and documentation and Google<br />

searches aren’t turning up what you need, don’t hesitate to ask “the<br />

community”. Most of us enjoy a challenge, but please remember to do your<br />

homework first. If you haven’t already read the ‘Smart <strong>Questions</strong>’ FAQ, it<br />

will help you to pose a question that will get you the best possible answer -<br />

See: http://www.catb.org/~esr/faqs/smart-questions.html<br />

24


Select n rows - How do you get<br />

just a few?<br />

• Query the database:<br />

SELECT <br />

FROM <br />

WHERE <br />

25<br />

25


But I only want…<br />

• Putting limits on the rows returned from a SELECT<br />

• Select-clause Keywords<br />

• New features in IDS v10.00xC3<br />

26<br />

26


FIRST, MIDDLE, … LAST?<br />

• SKIP offset (IDS v10.00.xC3)<br />

• FIRST max<br />

• LIMIT max (synonym for FIRST - IDSv10.00.xC3)<br />

• MIDDLE max (XPS only)<br />

27<br />

27


FIRST/LIMIT<br />

• Requires use of a max value<br />

SELECT FIRST 10 sales_reps, total_sales<br />

FROM sales ORDER BY total_sales DESC<br />

• Restrictions<br />

• View<br />

• Nested SELECT<br />

• Subqueries<br />

• Others…<br />

28<br />

LIMIT, introduced with IDSv10.00xC3 is a synonym for FIRST.<br />

28


MIDDLE<br />

• Available with XPS only<br />

• Requires use of a max value<br />

• Syntax and restrictions the same as for FIRST<br />

29<br />

29


SKIP<br />

• Requires use of an offset value<br />

SELECT SKIP 50 col1, col2 FROM table1<br />

SELECT SKIP 50 FIRST 10 col1, col2 FROM table1<br />

• Restrictions similar to FIRST<br />

30<br />

30


User-Defined Routines & SPL<br />

• Distinction between routines and functions<br />

• CURRENT<br />

• Dynamic SPL<br />

31<br />

31


What’s the difference?<br />

• Procedures<br />

• May accept arguments<br />

• Does not return values<br />

• Can not be used in <strong>SQL</strong> expressions<br />

• Functions<br />

• May accept arguments<br />

• Returns one or more values<br />

• Can be used in <strong>SQL</strong> expressions<br />

32<br />

Note - because procedures do not return values, they cannot be used in an <strong>SQL</strong><br />

expression.<br />

32


Why doesn’t the time change?<br />

• CURRENT<br />

• Returns the date/time the routine was started<br />

• Standard behavior - it isn’t a bug<br />

• SELECT DBINFO(‘utc_to_datetime’, sh_curtime)<br />

FROM sysmaster:sysshmvals<br />

33<br />

33


Can I use dynamic SPL?<br />

• No! Not by default, anyway.<br />

• exec bladelet (IDS v9.x)<br />

• IBM DeveloperWorks<br />

34<br />

http://www-<br />

128.ibm.com/developerworks/db2/zones/informix/library/samples/db_downloa<br />

ds.html<br />

34


Query Estimates<br />

• What does that query estimate really mean?<br />

• Compare estimates between modified versions<br />

of the same statement<br />

• How is the query estimate determined?<br />

• It depends on who you ask<br />

35<br />

Discussion.<br />

For more, see John Miller III sessions and Chat with the Lab presentations for<br />

a comprehensive discussion.<br />

35


Newlines<br />

• How do you remove newlines in text?<br />

• "tr -d '\015'"<br />

• C program<br />

• Others?<br />

36<br />

Discussion.<br />

There are many suggested methods of removing newlines from text. There are<br />

a number of solutions provided at comp.databases.informix.<br />

36


Resources<br />

• IBM <strong>Informix</strong> manuals on-line<br />

http://www.ibm.com/software/data/informix/pubs/library/<br />

• IIUG SIGs (Special Interest <strong>Group</strong>s)<br />

http://www.iiug.org/<br />

• Google<br />

http://groups.google.com/advanced_search<br />

37<br />

37


More help -<br />

• IIUG website - IBM <strong>Informix</strong> Links<br />

• Smart <strong>Questions</strong>:<br />

http://www.catb.org/~esr/faqs/smart-questions.html<br />

38<br />

38


Session L04<br />

<strong>Common</strong> <strong>SQL</strong> <strong>Questions</strong>: Why and How-to<br />

June C. Hunt<br />

Tyler Technologies Inc., MUNIS Division<br />

jhunt@munis.com<br />

june@iiug.org<br />

39<br />

39

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!