Sunteți pe pagina 1din 6

Version 1.

0
10+ tips for working smarter with SQL June 11, 2009

By Susan Sales Harkins


Your users probably don't know a thing about SQL, but you know its value. It's everywhere, it's easy to learn, and
SQL solutions are simple to implement. Whether you use SQL a lot or sparingly, working smarter with SQL will
help you avoid errors and improve performance.
Many SQL are vendor-specific. The following tips apply to Jet and Transact-SQL, but most SQL products are
similar.

1: Working with Jet SQL in the Access SQL window


Access users create SQL statements every time they create a query; they just don't know it. They're using the
Query Design window, a graphic representation of the actual SQL. Most users can't create the appropriate SQL
statements they need, so the graphical interface is helpful, but it can help you too. If you can't create errorless
SQL code off the top of your head, let the SQL window help out:

• Create a query using the Query Design window and then copy the code from the SQL window into a VBA
module for use in code.
• When a query in code returns one of VBA's meaningless error messages, copy the SQL statement to the
SQL window and run it. Access will usually return better information about the error than VBA.
• You can't always copy a SQL statement straight from the module to the SQL window. If the statement
includes concatenation or variables, add a Debug.Print statement right after the definition statement.
Then, if you need to debug the statement, copy the evaluated statement from the Immediate window. For
instance, the following statement in code won't run in the SQL window because of the variables and
concatenation:

"SELECT * FROM " & tbl & " ORDER BY " & fld

However, if you follow the statement with a Debug.Print statement, you can copy the evaluated results, which
follow, from the Immediate window:

SELECT * FROM Employees ORDER BY HireDate

2: Words reserved by SQL


SQL reserves several words, such as keywords. Avoid using these words to name columns, tables, variables, or
any objects. Their use outside of the context in which the engine expects them confuses the engine and
generates errors, or worse -- incorrect results.

3: The difference between ALL, DISTINCT, and DISTINCTROW


SQL's SELECT statement supports three predicates: ALL, DISTINCT, and DISTINCTROW. ALL is the default and
returns all records that fulfill any specified conditions. DISTINCT limits the results to unique values in a specific
column or columns. For instance, the following statement would return only one record for each LastName value:

SELECT DISTINCT LastName

In other words, if you have a record for both John and Mary Smith, this statement returns only one record for
Smith. However, DISTINCT works with all the columns, not just the column that immediately follows. That means,
this statement will return a record for both John and Mary because the combined columns don't produce a
duplicate record:

SELECT DISTINCT LastName, FirstName

Page 1
Copyright © 2009 CNET Networks, Inc., a CBS Company. All rights reserved. TechRepublic is a registered trademark of CNET Networks, Inc
For more downloads and a free TechRepublic membership, please visit http://techrepublic.com.com/2001-6240-0.html
10+ tips for working smarter with SQL

If the SELECT clause references more than one column, the combination of values from all the selected columns
must be unique for a given record.
DISTINCT has a few quirks you should know about but might not expect:

• Don't use DISTINCT with the asterisk character (*). You must specify columns by name.
• Any query using DISTINCT isn't updatable, which makes sense.
• While DISTINCT works with columns, DISTINCTROW works with records. (Transact-SQL doesn't support
DISTINCTROW.) This predicate has a few limitations of its own, which can make an error hard to
troubleshoot:
• The engine ignores DISTINCTROW if there's only one table in the query.
• The engine ignores DISTINCTROW if you reference all columns from all of the underlying tables.

4: Retrieving only what you need


It's tempting to use the asterisk character (*) when retrieving data via a SELECT clause, but don't, unless you
really need to retrieve all columns. The more data you retrieve, the slower your application will perform. For
optimum performance, retrieve only the columns you need.

5: Variations in aggregates
Both SQL and VBA support aggregate functions, but not the same aggregates. Although they aren't
interchangeable, you can often use one or the other. Table A compares the two types within the context of Jet
and Transact-SQL.

Table A
T-SQL Jet VBA Explanation Considers Null

Avg Avg DAvg Returns the mean or average of the specified No


domain

Count Count DCount Counts the number of non-Null values in the No


specified column

Count(*) Count(*) DCount(*) Counts the number of rows Yes

Sum Sum DSum Totals the values in the specified column No

Min Min DMin Returns the smallest value No

Max Max DMax Returns the largest value No

First Returns the value from the first row in the Yes
specified column

Last Returns the value from the last row in the Yes
specified column

StDev StDev DStDev Returns sample standard deviation No

StDevP StDevP DStDevP Returns population standard deviation No

Var Var DVar Returns sample variance No

VarP VarP DVarP Returns population deviation No

Page 2
Copyright © 2008 CNET Networks, Inc., a CBS Company. All rights reserved. TechRepublic is a registered trademark of CNET Networks, Inc
For more downloads and a free TechRepublic membership, please visit http://techrepublic.com.com/2001-6240-0.html
10+ tips for working smarter with SQL

Don't use VBA's domain aggregates when a SQL aggregate will do. When you must use VBA's domain
aggregates, apply an index to the underlying column for best performance. Keep in mind that although SQL's
GROUP BY doesn't eliminate null values, most SQL aggregates don't evaluate them. If you want null values
considered, you must accommodate them in the expression.

6: GROUP BY considerations
SQL's GROUP BY clause defines subsets of data. The most important thing to remember when including a
GROUP BY clause is to include only those columns that define the subset or summarize data for the subset. In
other words, a GROUP BY can't include extraneous data. For instance, to learn the number of orders placed on a
specific date, you'd use a statement similar to the following:

SELECT OrderDate, Count(OrderID)


FROM Orders
GROUP BY OrderDate

This query would return one record for each date. Each record would display the date and the number of orders
for that date. You can't include any other columns.
GROUP BY is versatile. You don't need to specify a column in the SELECT clause to group by it. For instance,
you could omit OrderDate from the above query and return just the count for each date (although the results
wouldn't make much sense). As long as the GROUP BY column is in the source, SQL doesn't require it in the
SELECT clause. On the other hand, if you refer to a column in the SELECT clause, you must also include it in the
GROUP BY clause or in an aggregate function. For instance, the following statement doesn't work because the
Freight column isn't part of an aggregate or the GROUP BY clause:

SELECT OrderDate, Count(OrderID) AS TotalForDate, Freight


FROM Orders
GROUP BY OrderDate

In truth, it doesn't really make sense to try to include a column in this way. If you want the Freight data within the
context of a GROUP BY query, you probably want a summary of the freight values in the group, as follows:

SELECT OrderDate, Count(OrderID) Max(Freight)


FROM Orders
GROUP BY OrderDate

Jet can't group a Memo or OLE Object column. In addition, you can't include a GROUP BY clause in an UPDATE
statement, which makes sense. SQL would have no way of knowing which record to update.

7: Altering table structure


There are several SQL statements for altering the design of a table. Always approach such a task with care
because you could destroy data. For instance, if you change a column's data type, the engine might truncate or
delete existing data to accommodate the new column's data type. Keep the following limitations in mind when
altering tables:

• You can't alter an existing column's data to COUNTER if the column already contains data.
• You can't rename a column. You must remove the column using DROP COLUMN and then re-create it
using the new name. To preserve the data, create the new column, copy data from the original column
using UPDATE, and then delete the original column.
• Before altering a table using ALTER TABLE, close it. Otherwise, the engine will return an error. The
following VBA code will close an open table and inhibit the error that's generated if the table isn't open:
On Error Resume Next
DoCmd.Close acTable, table
On Error GoTo 0

Page 3
Copyright © 2008 CNET Networks, Inc., a CBS Company. All rights reserved. TechRepublic is a registered trademark of CNET Networks, Inc
For more downloads and a free TechRepublic membership, please visit http://techrepublic.com.com/2001-6240-0.html
10+ tips for working smarter with SQL

• You can't delete a column if a constraint exists on that column. First, delete the constraint using DROP
CONSTRAINT.
• Remove a CHECK CONSTRAINT before deleting the table to which it applies.
• You can't modify an existing relationship. You must delete it and then re-create it.

8: SQL's problem child, INSERT INTO


SQL's INSERT INTO statement lets you add new data to an existing table. Used correctly, INSERT INTO works
great, but you must remember one critical thing: Although the table designs don't have to match, the specific
columns identified on both sides of the task must match. In short, the table that receives the new data must
contain the same columns as the incoming data.
You can also explicitly identify each column using the VALUES clause as follows:

INSERT INTO target (col1, col2, col3, …)


VALUES(value1, value2, value3, …)

However, this syntax adds only a single row at a time, so it will have limited use. You can omit the column
references only if you supply a value for every column in target. When including the column references, their
order must match the order in the table definition. You must include the primary key column, unless that key is an
auto-numbering column -- it isn't necessary to include an auto-numbering column.

9: Using UPDATE to delete values


SQL's DELETE statement deletes entire records. The statement won't return an error if you specify a list of
columns, but it will ignore the list. For instance, the following statements would delete all the data in a table
named Employees:

DELETE
FROM Employees

DELETE Employees.*
FROM Employees

DELETE Employees.Salary
FROM Employees

Even though the last syntax specifies Salary, SQL will delete all the data, not just the Salary values. To delete
specific values, use SQL's UPDATE in the form:

UPDATE source
SET source.column = Null
[WHERE condition]

However, even this will return an error if column properties are in conflict. For instance, if a column requires data,
it will reject Null.

10: Dropped properties with SELECT INTO


SQL's SELECT INTO creates a new table by copying rows from an existing table using the following form:

SELECT list|* INTO newtable


FROM sourcetable
[WHERE condition]

Page 4
Copyright © 2008 CNET Networks, Inc., a CBS Company. All rights reserved. TechRepublic is a registered trademark of CNET Networks, Inc
For more downloads and a free TechRepublic membership, please visit http://techrepublic.com.com/2001-6240-0.html
10+ tips for working smarter with SQL

However, this statement doesn't copy the table exactly. It won't copy the original table's primary key, indexes, or
column and table properties (beyond the default settings). In addition, it ignores Caption settings and uses the
original column names.
When including a SELECT INTO statement, keep in mind that this statement will replace an existing table if one
of the same name (newtable) exists within its scope. Fortunately, SQL will warn you first. In some cases, the
engine will delete the existing table before it actually creates the new one, so if something goes wrong, you can't
rely on the original table because it'll be gone. Before running a SELECT INTO, it's a good idea to make a copy of
the existing newtable, if one exists. In addition, if newtable is open, SQL will return an error.
You don't have to copy data to the new table. You can create a new empty table by adding a WHERE clause as
follows:

SELECT * INTO newtable


FROM source
WHERE FALSE

SQL will create newtable but copy no data to it because no record can satisfy the FALSE condition.

11: The difference between WHERE and HAVING


The WHERE and HAVING clauses perform similar functions but they aren't interchangeable. WHERE limits the
data returned by the SELECT clause; therefore, a GROUP BY is inconsequential. The engine compares data and
eliminates records that don't satisfy the WHERE clause before it groups the records. On the other hand, the
HAVING clause eliminates data that doesn't satisfy the grouping criteria.
If you have trouble remembering which clause to use, remember that the WHERE clause is positioned before the
GROUP BY clause and the engine applies the WHERE clause before grouping the records.

12: UNION matchup


SQL's UNION operator lets you combine records from different sources using the following form:

SELECT1 list|*
UNION
SELECT2 list|*
The important thing to remember with a UNION is that the column order in both SELECT statements must match.
The column names don't have to match, but each list must contain the same number of columns and their data
types must be compatible. If the data types don't match, the engine sometimes chooses the most compatible for
you. The results might work, but then again, they might not.
By default, UNION sorts records by the values in the first column because UNION uses an implicit DISTINCT
predicate to omit duplicate records. To include all records, including duplicates, use UNION ALL, which eliminates
the implicit sort. If you know there are no duplicate records, but there are a lot of records, you can use UNION
ALL to improve performance because the engine will skip the comparison that's necessary to sort (to find
duplicates).

Page 5
Copyright © 2008 CNET Networks, Inc., a CBS Company. All rights reserved. TechRepublic is a registered trademark of CNET Networks, Inc
For more downloads and a free TechRepublic membership, please visit http://techrepublic.com.com/2001-6240-0.html
10+ tips for working smarter with SQL

Additional resources

TechRepublic's Downloads RSS Feed


Sign up for the Downloads at TechRepublic newsletter
Sign up for our IT Leadership Newsletter
Check out all of TechRepublic's free newsletters
10+ tips for upsizing an Access database to SQL Server
How do I... Reseed a SQL Server identity column?
10+ tips for getting the best performance out of your SQL Server data types

Version history
Version: 1.0
Published: June 11, 2009

Tell us what you think

TechRepublic downloads are designed to help you get your job done as painlessly and effectively as possible.
Because we're continually looking for ways to improve the usefulness of these tools, we need your feedback.
Please take a minute to drop us a line and tell us how well this download worked for you and offer your
suggestions for improvement.

Thanks!

—The TechRepublic Content Team

Page 6
Copyright © 2008 CNET Networks, Inc., a CBS Company. All rights reserved. TechRepublic is a registered trademark of CNET Networks, Inc
For more downloads and a free TechRepublic membership, please visit http://techrepublic.com.com/2001-6240-0.html

S-ar putea să vă placă și