SQL For Developers - Basic Data Retrieval - CodeProject
SQL For Developers - Basic Data Retrieval - CodeProject
1 of 8
http://www.codeproject.com/Articles/145134/SQL-for-Developers-Basi...
Sign in
home
articles
quick answers
discussions
features
community
help
CPOL
Rate this:
Introduction
As a software developer, I am often called upon to write SQL queries to retrieve data from the database. Since being the DBA is part of
6/11/2015 12:58 AM
2 of 8
http://www.codeproject.com/Articles/145134/SQL-for-Developers-Basi...
my role, I have found it quite natural to do so. However, I have come across a number of developers who do not understand how to write
an efficient T-SQL command. This article is designed with the developers in mind but it will be equally useful for database developers who
want to brush up on their skills. This particular article focuses on the basics of how to retrieve data from a database.
Purpose
Throughout this article I will cover the basics of how to access data from a SQL database as well as my suggestions for how to best use
each of these tools. Most of these techniques should work on any modern version of Microsoft SQL. I will do my best to point out when
commands are only available in certain versions of SQL. All queries have been designed to run against the AdventureWorks database.
Microsoft provides this sample database for free on their website.
Please note that it is outside the scope of this document to really discuss in depth how these queries should be called (from code directly
or through stored procedures). I would say that, when in doubt, use a stored procedure.
Standard Commands
The first thing you learn when being taught how to access data in a database are the following commands: SELECT, FROM, WHERE,
ORDER BY. These command are the foundation on which most queries are built. SELECT tells the system what columns you want, FROM
says where to get the columns, WHERE filters the results, and ORDER BY puts the results into the desired order. Here is a basic example of
this type of query:
Hide Copy Code
ProductNumber
------------------------CR-7833
GL-F110-L
GL-F110-M
GL-F110-S
GL-H102-L
Color
--------------Black
Black
Black
Black
Black
Best Practice: The ORDER BY command can order in ascending or descending order. This is specified by an ASC or DESC after the
column name. If you do not specify anything, the column is sorted ascending. However, it is good practice to write this out instead of
leaving it implied.
Best Practice: While SELECT * will give you every column, avoid this method if at all possible. By specifying which columns you want, you
will reduce the bandwidth needed to transfer the results to the client.
Key Point: You do not need to have a column listed in the SELECT statement in order to use it in the WHERE clause. It simply needs to be
a column in one of the referenced items in the FROM statement.
Key Point: Query sections get evaluated in the following order: FROM, WHERE, SELECT, ORDER BY. This means that if you create an alias
(see below) in your SELECT statement, the WHERE statement will not be able to reference it (since it hasnt been evaluated yet) but the
ORDER By statement can use it.
Key Point: Query results are not ordered unless specifically given an order. It may seem like they are always returned in the same order
without an ORDER BY statement but this is not reliable. If you want your records returned in a specific order, you must specify it.
SELECT Name,StandardCost
6/11/2015 12:58 AM
3 of 8
http://www.codeproject.com/Articles/145134/SQL-for-Developers-Basi...
FROM Production.Product
WHERE Name = 'HL Bottom Bracket'
Name
StandardCost
-------------------------------------------------- --------------------HL Bottom Bracket
53.9416
(1 row(s) affected)
What if, however, we wanted every bottom bracket in our database, not just the HL Bottom Bracket? In that case, we could use the LIKE
keyword instead of the equals in our WHERE statement and use the percent (%) sign to represent a multi-character wildcard. That query
would look like this:
Hide Copy Code
SELECT Name,StandardCost
FROM Production.Product
WHERE Name LIKE '% Bottom Bracket'
Name
-------------------------------------------------HL Bottom Bracket
LL Bottom Bracket
ML Bottom Bracket
StandardCost
--------------------53.9416
23.9716
44.9506
(3 row(s) affected)
That gives us the results we wanted but at a fairly significant cost. The first query used an Index Seek (very efficient) while this second
query uses an Index Scan (inefficient). The reason for this is because we put the wildcard at the beginning of the statement. Sometimes
you cannot help this. For example, in this query it would be very difficult to find all of the items with the text Bottom Bracket" in their text.
Moving the wildcard anywhere else in the text will allow the system to do an Index Seek again.
Best Practice: When you have multiple statements in the WHERE section, use parenthesis to ensure the proper order of execution. For
example, (Name=Wrench AND Color=Blue) OR Color=Black is different from Name=Wrench AND
(Color=Blue OR Color=Black).
Best Practice: As we learned above, avoid putting a wildcard character at the beginning of the search text. This will dramatically improve
the performance of your query.
Best Practice: Avoid performing functions on the left side of a WHERE statement. For example, the following would be functionally
equivalent to the query we did above but it would actually perform even worse than our existing poorly performing query:
Hide Copy Code
SELECT Name,StandardCost
FROM Production.Product
WHERE SUBSTRING(Name,4,14) = 'Bottom Bracket'
Name
-------------------------------------------------LL Bottom Bracket
ML Bottom Bracket
HL Bottom Bracket
StandardCost
--------------------23.9716
44.9506
53.9416
(3 row(s) affected)
StandardCost
--------------------2171.2942
2171.2942
2171.2942
2171.2942
2171.2942
(5 row(s) affected)
6/11/2015 12:58 AM
4 of 8
http://www.codeproject.com/Articles/145134/SQL-for-Developers-Basi...
If you wanted to return the top five percent of your products based upon price, you would simply modify the above statement to begin
StandardCost
--------------------77.9176
308.2179
601.7437
(3 row(s) affected)
Name
-------------------------------------------------Mountain End Caps
LL Road Frame - Red, 52
Mountain-200 Black, 38
StandardCost
--------------------0.00
187.1571
1251.9813
(3 row(s) affected)
Key Point: The method I showed you of finding the most expensive items does not take into account items with the same price. In my
example, all five items that return have the same Standard Cost. If I only wanted the top three, which ones would it give me? The answer is
the first three it found. This order might change without notice unless you had specified a second column to order by as well.
StandardCost
--------------------3.3963
3.3963
3.7363
(3 row(s) affected)
I limited the results to three since this is a demonstration query. Notice that I renamed the Name column to be Product_Name so that it
was easier to read. It would make even more sense if we had a query that contained a customers name as well as the product name.
I intentionally made this query a bit tricky just to show off what we have already discussed. Notice that the WHERE clause references the
6/11/2015 12:58 AM
5 of 8
http://www.codeproject.com/Articles/145134/SQL-for-Developers-Basi...
Name column while the ORDER BY clause references the Product_Name column. Remember this is because the WHERE clause is evaluated
before the SELECT while the ORDER BY is evaluated after the SELECT. If we wanted to use the name Product_Name in our WHERE clause,
we could do so like this:
Hide Copy Code
SELECT TOP 3 *
FROM (
SELECT Name AS Product_Name, StandardCost
FROM Production.Product
) AS Prod
WHERE Product_Name LIKE 'Mountain%'
ORDER BY Product_Name ASC
Product_Name
-------------------------------------------------Mountain Bike Socks, L
Mountain Bike Socks, M
Mountain Bottle Cage
StandardCost
--------------------3.3963
3.3963
3.7363
(3 row(s) affected)
Basically we need to create the query (without limits) inside of parenthesis and use that as the table in the FROM statement. Notice that we
named the entire nested query as Prod. You need to name the query something so that you can reference it. The end result of all of this is
the same except that we could use the column name Product_Name in our WHERE clause. When doing this, be careful to place items in
the right query. For example, I put my TOP 3" limiter in the outer query instead of the inner query because otherwise I would have gotten
bad results (we need to apply our WHERE to the entire table, not just three records).
SELECT StandardCost
FROM Production.Product
WHERE StandardCost BETWEEN 1 AND 2
StandardCost
--------------------1.8663
1.8663
1.4923
1.8663
(4 row(s) affected)
The syntax is easy enough to read. This method is syntactically equivalent to the following statement:
Hide Copy Code
SELECT StandardCost
FROM Production.Product
WHERE StandardCost >= 1
AND StandardCost <=2
StandardCost
--------------------1.8663
1.8663
1.4923
1.8663
(4 row(s) affected)
If you look at the execution plan, these two statements actually evaluate to the same plan which means there is no performance gain or
loss by using the BETWEEN operator. The biggest thing we gain is a simpler statement. Note that the BETWEEN operator includes the
lower and upper ends so if there were an item that sold for 2 dollars it would be included in this list. The same would be true for an item
that cost one dollar.
The next operator we want to look at is the IN operator. This operator tells the system to find an exact match to one of the items in the
list. The list can have two or more items in it. Here is an example of how to use the IN operator:
Hide Copy Code
SELECT StandardCost
FROM Production.Product
6/11/2015 12:58 AM
6 of 8
http://www.codeproject.com/Articles/145134/SQL-for-Developers-Basi...
SELECT StandardCost
FROM Production.Product
WHERE StandardCost = 1.8663
OR StandardCost = 44.9506
OR StandardCost = 1.4923
StandardCost
--------------------1.8663
1.8663
1.4923
1.8663
44.9506
(5 row(s) affected)
While the execution plan does not write out the translation of this query, it executes the same plan for both of these queries. Again, this
means that the IN operator does not cause any performance gains or losses. It is simply an easier way to write out our query.
Advanced Topics
I have intentionally not covered some of the advanced topics including grouping of results, temporary tables, parameters and other
important T-SQL topics. I intend to cover these and more in my next article. SQL has a lot to offer developers. While it would be great if
you could read a good SQL book or two completely in order to get a full picture of how to build SQL statements properly, I intent to give
you the condensed version in these articles.
Conclusion
In this article, we have learned how to use the basic commands and operators in T-SQL statements. With this knowledge you can build
simple commands to gather data from one or more tables in Microsoft SQL. Along the way we discussed some of the best practices that
should be followed as well as a few gotchas that we should be aware of when building our queries. I hope you have found at least
something that could be of benefit to you from this article. I appreciate constructive feedback and look forward to your thoughts on how
this article could be approved.
History
January 11, 2011: Initial version
License
This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)
Share
EMAIL
6/11/2015 12:58 AM
7 of 8
http://www.codeproject.com/Articles/145134/SQL-for-Developers-Basi...
Tim Corey
Software Developer (Senior) Epicross
United States
I am currently a Lead Technical Consultant for a consulting company called Epicross. My primary
skills are in .NET, SQL, JavaScript, and other web technologies although I have worked with
PowerShell, C, and Java as well.
In my previous positions, I have worked as a lead developer and IT Director. As such, I have been
able to develop software on a number of different types of systems and I have learned how to
correctly oversee the overall direction of technology for an organization. I've developed
applications for everything from machine automation to complete ERP systems.
My current position is mainly focused making our clients more efficient and effective. I use
custom software (desktop, mobile, and web) to help facilitate this goal. When I'm not working
for the company, I'm usually developing applications to fill the needs of the organizations I
volunteer for.
XQuery basics
Search Comments
Profile popups
Spacing Relaxed
Layout Normal
Per page 25
Update
My vote of 5
Richard MacCutchan
31-Jan-13 3:28
My vote of 5
stevepb
7-Mar-11 10:54
My vote of 4
Slacker007
23-Jan-11 1:39
My vote of 5
thatraja
21-Jan-11 18:13
6/11/2015 12:58 AM
8 of 8
http://www.codeproject.com/Articles/145134/SQL-for-Developers-Basi...
My vote of 5
linuxjr
My vote of 5
Vivek Johari
20-Jan-11 1:47
Tim Corey
27-Jan-11 4:06
Re: My vote of 5
Suggestions &1 comment
21-Jan-11 16:19
KP Lee
17-Jan-11 20:09
Tim Corey
18-Jan-11 5:03
KP Lee
18-Jan-11 10:59
My vote of 5
slam Iqbal
17-Jan-11 2:39
Pranay Rana
16-Jan-11 22:40
Erik Anderson
11-Jan-11 11:19
Tim Corey
11-Jan-11 11:29
Tim Corey
11-Jan-11 11:41
Erik Anderson
11-Jan-11 14:24
cdkisa
11-Jan-11 8:47
General
News
Suggestion
Question
Refresh
Bug
Answer
Joke
Praise
Rant
Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.
Select Language
Layout: fixed |
fluid
6/11/2015 12:58 AM