Common SQL Questions - International Informix Users Group
Common SQL Questions - International Informix Users Group
Common SQL Questions - International Informix Users Group
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