blogs.conchango.com

welcome to the conchango blogging site
Welcome to blogs.conchango.com Sign in | Join | Help
in Search

SSIS Junkie

T-SQL: Do you use aliases?

A pet peeve of mine is the lack of alias usage when using T-SQL. I’m not sure why people don’t bother using aliases –I’ve never asked- but I suspect its laziness. I can understand that but I want to speak up for the bastion of embattled SQL developers out there that have to do that much-feared task in an IT shop – debugging someone else’s code.

Take the following code:

 

select OBJECT_NAME(resource_associated_entity_id) LockedObj , status , login_name from sys.dm_tran_locks inner join sys.dm_exec_sessions on request_session_id = session_id where resource_type = 'object'

 

Its a query that provides information about locks on a SQL Server instance. Now many of you reading this know a lot about sys.dm_tran_locks and sys,dm_exec_sessions but equally a lot of people don’t and so it is not obvious which table/view the [status], [login_name], [resource_type], [resource_associated_entity_id], [request_session_id] and [session_id] fields actually come from. Would it not be better to write it like this?:

select OBJECT_NAME(l.resource_associated_entity_id) LockedObj , s.status , s.login_name from sys.dm_tran_locks l inner join sys.dm_exec_sessions s on l.request_session_id = s.session_id where l.resource_type = 'object'

Of course it would. Ambiguity has been removed and the query is much easier to understand. Perhaps this example doesn’t strike a chord with you because you are pretty familiar with SQL Server’s DMVs but take a look at the following query that is indicative of some code I recently inherited:

 

select id , name , quantity , address1 , address2 , city , postcode from Customers inner join Orders on id = s_id and ref = 'QWERTY'

 

Where do all those columns come from? Its hardly clear is it? Are those address fields the customer’s address or the delivery address for the order? Which table has [id] as an identifier?  [I’m actually simplifying the problem. There are a lot more tables and columns at play in the code I inherited]

So that’s my first gripe about aliases; If you don’t include them then the code is harder to understand. My second gripe is about misuse of aliases. Again, let’s take a look at some code:

update existingCustomers set existingCustomers.name = newCustomers.name , existingCustomers.address1 = newCustomers.address1 , existingCustomers.address2 = newCustomers.address2 from newCustomers inner join existingCustomers on newCustomers.id = existingCustomers.id

In this example the developer has prefixed all the columns with the name of the table rather than a table alias so now the same information is scattered throughout the query rather than in just one place. Debugging code often involves creating replicas of tables so that we can play around without affecting live data and in this situation its no inconceivable that I need to create a table called [existingCustomers_temp]. If I want to use the code above against my new table then I have to and make edits in six different places. If the code were written like this:

 

update e set e.name = n.name , e.address1 = n.address1 , e.address2 = n.address2 from newCustomers n inner join existingCustomers e on n.id = e.id

 

I only have to make one edit. In my opinion it looks a lot neater as well. I like conciseness where appropriate..

I implore you to use aliases and use them correctly. Especially if I am ever going to be inheriting your code!

-Jamie

Published 04 July 2008 20:58 by jamie.thomson
Filed under: ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

James.Rowland-Jones said:

On the money as usual JT...

How about prefixing your attributes with *something* to denote the entity to which it belongs? This does have some advantages around foreign keys and joins in particular.  It also uniquely identifies the attribute in the DDL and so forces the developer into showing the source entity.  However, it can lead to long names for attributes and you can end up with something close to your last but one example.  If you are going to do it I guess you need to have a code for the entity to abbreviate it.

Taking the alias question one step further...

How do you feel about column aliases?  Do you think they add anything to the understanding of the code or do you think their purpose is purely to abstract the column name?  They can of course also be used to undermine any coding structure in the DDL to uniquely identify the attribute in the first place :-).

Cheers, JRJ

July 4, 2008 21:28
 

Madhivanan said:

July 4, 2008 21:37
 

Scott Whigham said:

Thanks, Jamie, for suggesting this lol. I too often have to work with (a) code with little or no formatting, (b) code with too much formatting, (c) code w/ keywords in lowercase, (d) code w/ no aliases, (e) code with useless/difficult aliases (e1, e2 in recursive parent/child queries), etc, etc, etc :)

So definitely: use aliases and give them a mnemonic name!

July 4, 2008 21:43
 

David Walker said:

WHAT???  PLEASE don't say that the lack of aliases is due to laziness.  I *hate* aliases that are not necessary.  And 99.9% of the aliases that I see aren't necessary.  Put the name of the table in front of the column name!  

I have a really hard time debugging other people's T-SQL code when they use gratuitous aliases in their Join statements, especially.  Copy and paste the name of the tables that you had to type in the Join statement, into the ON clause, people, it's not that hard.

When there are aliases floating around everywhere, I have to mentally decompose the aliases into the underlying table names in order to understand what is being joined and what is being selected.  It is easy for SQL to do that, but much harder for humans to do that.

PLEASE don't try to get people to use aliases more, try to get them to use aliases LESS.  Aliases are rarely necessary (except for derived tables, and correlated subqueries, and situations like that).  

In the situation that you mention, where you have to change the name of a table and you gripe that the information is scattered throughout the query -- well, even if you have to make a temp table, you need to look at all the places where that temp table is used to make sure it's correct.  A good Replace in any decent SQL query tool will make the changes for you.

Personally, I would write that as:

update  existingCustomers

set     name = newCustomers.name

,       address1 = newCustomers.address1

,       address2 = newCustomers.address2

from    newCustomers

inner   join existingCustomers

on      newCustomers.id = existingCustomers.id

Now, THAT is clear.  And easy to read.  And it tells me, at a glance, which table the new data is coming from.

Personally, I think unneccessary aliases should be considered bad programming practice.

What you are objecting i nthe first gripe to is the lack of fully qualifying the column names, not the lack of aliases.  Please, I beg you, don't ask people to use aliases more.  Ask them what you really are looking for, which is to qualify the column names with the names of the tables in a big Select statement.  Having to figure out which table is "l" and which is "I" is harder than seeing the whole table name there.

Thank you.

David Walker

July 4, 2008 22:02
 

Dew Drop - July 6, 2008 | Alvin Ashcraft's Morning Dew said:

July 6, 2008 13:53
 

Ben Eaton said:

Re: David Walker's comments - I couldn't disagree more!!

Well written, set-based, T-SQL will *always* benefit from aliases.  I encourage developers/DBAs to use an alias even where there is only 1 table involved, if only to improve the maintainability of the code (aliases make it easier to turn queries into subqueries, replace tables names etc).  If code is unreadable then it is usually due to the complexity rather than the number of aliases.  The thing that causes the most difficulty when trying to mentally parse a statement is poor/untidy formatting.

This can be illustrated with the following SELECT query on the Northwind database:

SELECT

C.CompanyName,

P.ProductName,

OD.Quantity,

ISNULL(E.FirstName + ' ','') + ISNULL(E.LastName,'') [EmployeeName]

FROM

Customers C

INNER JOIN

Orders O

INNER JOIN

[Order Details] OD

INNER JOIN

Products P

ON

OD.ProductID = P.ProductID

ON

O.OrderID = OD.OrderID

INNER JOIN

Employees E

ON

O.EmployeeID = E.EmployeeID

ON

C.CustomerID = O.CustomerID

WHERE

C.CompanyName Like 'A%'

It's simple but it illustrates how well-chosen aliases in a well-formatted piece of T-SQL can be easily understood.  The formatting of the joins ensures that it is clear which table joins which, as well as the join tree for further dependencies while avoiding joins that occur outside of the scope of the nest.

I think you have to ask how many tables are really used in a single query and whether it can be simplified by using views, common table expressions, or derived tables.  I believe intelligent use of aliases provides a good compromise between maintainability and flexibility.

The real question is whether or not to use the AS keyword...

July 6, 2008 16:37
 

Ben Eaton said:

...and let that be a lesson to me - my wonderful T-SQL formatting destroyed like a Dalek masterplan.  Turning tabs into carriage returns indeed!

July 6, 2008 16:41
 

Paul Smith said:

Lets have the alises, and while we are at keep to ANSI standard SQL ;-)

July 6, 2008 16:47
 

Bill said:

I would argue that columns should always be qualified and aliases are to be used _if_ they provide clarity.  

One of the other reasons I have adopted the qualify column names mantra is future growth.  Sure, the query only has one table in it now so obviously everything comes from table Foo but the next feature will require that one column from Bar and with that 5 piece natural key between them, it's going to be a royal PITA.

newCustomers.Column1 and existingCustomers.Column2 is an excessive amount of typing and unless there are serious checks put on code going into production, that rule would quickly fall by the wayside.  A compromise would be something that won't cause the pain of "Is 'A' newCustomers or existingCustomers" and would still provide a shorthand version of the table.  Perhaps something like NC/EC or NEW/OLD,  I find that certain lingo develops in shops that would make an insightful alias obvious.

One thing that can help in the situation where you might want to sub in a temp table is to alias it with the base table's name, thus

from    newCustomers

inner   join existingCustomers_temp AS existingCustomers

I'm sure you've thought of it but in case others stumble upon this, it's one of my hacks.

July 6, 2008 16:58
 

Steve Jones said:

Can't be laziness. If they were lazy, they'd use aliases to save typing the table names.

Please don't say it's not clear.

If you can't decode this in 2 sec, you might want to consider another profession.

update  eC

set     name = nC.name

,       address1 = nC.address1

,       address2 = nC.address2

from    newCustomers nc

inner   join existingCustomers ec

on      nC.id = eC.id

If you don't want to use them and do the extra typing, no issue, but to say it's not clear?

July 7, 2008 19:22
 

Brian Schkerke said:

Ugh.  I hate aliases.  Why is gpnp meaningful?  Why is e meaningful?  It's not.  You complain that not fully qualifying the column name is lazy, but using aliases which do not convey a meaning is just as lazy.  One view that I have to maintain has thirty tables joined in it.  Each is aliases with some proprietary name which means *nothing* to me.  I end up bouncing from the top of the view definition to the bottom to figure out where a column is coming from.

I don't have a problem decoding

update  eC

set     name = nC.name

,       address1 = nC.address1

,       address2 = nC.address2

from    newCustomers nc

inner   join existingCustomers ec

on      nC.id = eC.id

I do think you're being lazy by not including the full tablename.  What, exactly, is the benefit from using nC and eC?  It's not to clarify.  Clarification would be to use the full table name.

I do have a problem decoding... bah, I can't paste it.  I'm not sure what the rules are for logic and such used here at my job.  Suffice to say, my views and SQL aren't as simple as the "examples" used here.  And it gets damned confusing to figure out all the aliases that made sense to someone else.  (For instance, gpnp vs pnp.  What's the difference?  Are they identical?  Here's a hint:  no.)

July 7, 2008 21:29
 

jamie.thomson said:

Quite the little tete-a-tete going on here isn't there :)

Keep it going...I'm enjoying the debate.

-Jamie

July 8, 2008 09:38
 

Colin Blair said:

My queries would look something like the following. I really don't like using non-meaningful aliases, it just seems lazy to use an alias but more importantly I have already build the database in my head with the original table names in place. If I have to learn a new set of table aliases every time I read a new query it just slows me down when I mentally execute the query. I do alias out the owner name which I always include in my queries for stability reasons but that is as far as I go. If I need to redirect the query for a quick test against a temp table I will change the table name and then just leave my original alias in place.

UPDATE

   existingCustomers

SET

   existingCustomers.name = newCustomers.name

,   existingCustomers.address1 = newCustomers.address1

,   existingCustomers.address2 = newCustomers.address2

FROM

       dbo.newCustomers newCustomers

   INNER JOIN

       dbo.existingCustomers existingCustomers

   ON  newCustomers.newCustomersId = existingCustomers.existingCustomersId

Now, an alias that has some meaning to it is a different matter:

UPDATE

   existingCustomers

SET

   existingCustomers.name = newCustomers.name

,   existingCustomers.address1 = newCustomers.address1

,   existingCustomers.address2 = newCustomers.address2

FROM

       dbo.Customers newCustomers

   INNER JOIN

       dbo.Customers existingCustomers

   ON    newCustomers.CustomersId > existingCustomers.CustomersId

   AND existingCustomers.Ssn = newCustomers.Ssn

July 8, 2008 20:41
 

Andrew Sears said:

Seems like a matter of opinion to me... I prefer aliases.  OD makes it so much easier to read than OrderDetails everywhere.  You shouldn't need to read a novel when all you want are the Coles Notes...

It's much less intrusive and requires less clicks to change the from clause table name with an alias associated rather than doing a bulk search/replace & hoping everything works out.  

Other than readability, I don't think there are any differences in performance.

More important for performance is object qualification to an owner/schema.  

http://tinyurl.com/5owarx

Understanding someone else's SQL & auto qualifying it is so much easier with SQL Refactor & SQL formatting tools.

http://www.sqlservercentral.com/articles/Product+Reviews/2923/

Note: I don't work for Red-Gate, just like their products. :)

So what are best practice suggestions when using SQL 2005 Synonyms?

July 8, 2008 22:38
 

jamie.thomson said:

The comment about "laziness" was a last-minute-throwaway thing cos I couldn't quickly think of anything else to put in the first line (how ironic). I don't really consider people that do not use aliases to be lazy. Honest.

-JT

July 9, 2008 12:42
 

Colin Blair said:

+1 on Red-Gate Refactor. I agree that questions like this are purely opinion and have a lot to do with how your brain is wired but it can be interesting to discuss. How about a new question: T-SQL: Do you use semi-colons?

heh heh

July 9, 2008 22:48
 

ranomore said:

Colin Blair: T-SQL: Do you use semi-colons?

Um, semi-colons? That's for Oracle databases. :)

I think aliases are particularly useful when you always use the same aliases for the same tables across all your queries in that database. Like we have a couple of tables in our database that get referenced in TONS of queries. One table is always aliased as r and the other as u.

And then, since those are base tables, there are other tables that have the name of the base table in their name, so aliases make those queries much less confusing.

July 10, 2008 05:37
 

Mike Hayes said:

For me,  aliases make the code more readable.  That's all.  Aliases should suggest the name.  Don't use:

FROM dbo.customer a INNER JOIN dbo.sales b

Rather:

FROM dbo.customer c INNER JOIN dbo.sales s

For reporting queries where you freqently join to 10 or more tables,  well-considered aliases make the code much more readable.  Remember,  you're mainly making this more readable for future edits of the code.  When you're immersed in the creation of the query,  it's not that important.  It's when the code has to be revisitied a year later.

July 13, 2008 19:35
 

Vern Rabe said:

For me, a minimum of two part naming significantly eases maintenance and understanding. The use of an alias instead of the table name (or schema.table) improves readability (if, as Mike says, well-considered aliases are used), and eases typing.

If you don't use semicolon statement terminators, you can encounter problems such as the following. Why is there no error due to the lack of an EXEC preceeding the execution of sp_who2, which is not the first statement in the batch - and it doesn't execute?

SELECT COUNT(*) FROM sys.databases

sp_who2

Vern

July 14, 2008 06:17
 

Chris Waldock said:

Couldn't agree more with Mike Hayes. I once was turned down at a job interview for pointing out the impractibility of aliases that bore no relation to the tablename. Turns out it was the interviewer's own piece of code, and he didn't like my comment!

Personally I feel that if I need a reasonably simple select statement then I won't bother with aliases - but if the statement references 3 or more tables then I will always use them.

July 14, 2008 09:20
 

Adam Tappis said:

My personal opinion is that aliases are very important but they need to be used intelligently.

By intelligently I mean that there's no point using random letters {a,b,c} or at the opposite end of the scale camel case senteces that are longer than the original table name.

This also stretched to CTE's. These should help reduce the need for sub-queries and are a far more readable way to structure your code. You wouldn't call your CTE's q1, q2 and q3 would you?

This brings me to the most important point, aliases by themselves don't do a great deal for code readibility. Structuring your SQL in a readable fashion has the highest impact. E.g. lining statements up rather than indenting. When looking at a query, being able to visually scan the query top to bottom in a strainght line allows you to do so much faster.

When I refer to aliases I mean table/sub-query alises and not column aliases which I dispise. I never write queries that look like

SELECT p.name person_name,

p.description person_description

FROM person p

Instead I would write:

SELECT  person_name = name

     , person_description = description

FROM    person

So column aliases are always in the format alias = expression - why? Because that way all the names of the columns that form the output of my qery are lined up on the left rather than staggered at the end of each line or some multi-line case statement - and no alias is required for a query with only one table in it.

When joining tables, I like to use brief UPPER CASE aliases to distinguish them from my object names which are usually all lowercase with under_scores. e.g.

SELECT  person_name   = P.name

     , person_adress = A.adress_line1

FROM    person          P

JOIN    adress          A

ON      P.adress_id   = A.adress_id

*(copy paste the query in a mono-spaced font to see the spacing)

Everyone has their own preferences but I think code formatting standards are firstly very personal and secondly are a much wider discussion of which aliases are just a small part.

Adam Tappis.

July 14, 2008 11:27
 

Adam Tappis said:

Oh, and personally I DO think that sacrificing code readibility for a the sake of hitting the space bar a few times IS laziness.

Also, whoever uses tabs instead of spaces (naming no names Ben Eaton) in their SQL needs a good talking to.

Adam.

July 14, 2008 11:33
 

Marianne Seggerman said:

I use aliases because they're so much faster to code (and the owner is too cheap to even shell out $200 bucks for a SQL Prompt package).  The lead developer never uses them but laboriously prefixes every reference with table name.  I think he had a trail SQL prompt when he developed them.  It is easier to understand his stored procedures than mine, although I am [mostly] consistant with my aliases.

July 14, 2008 14:20
 

Jim said:

You can just use a search and replace if you need to change the table name for testing purposes.  Customer means a lot more than to me than an alias of C.

My two cents!

July 20, 2008 16:32
 

wBob said:

Jamie, I am absolutely astonished that you have not used schemas in your sample queries!  I hate it when they leave the schema off, even if it's dbo.  ; )

I also understand this incurs a minor performance hit (for ad hoc queries) when the optimizer has to check the object doesn't exist in more than one schema.  Trifling?  No.  Self-documenting code, yes!

Same goes for aliases, I always use them when the query contains more than one table, if only because they answer the simple question, "What table does this column come from?"  I don't want to "decode it" !?? I want to know it, up-front.  The developer knows this when they write the query (probably); pass it on, don't hide it.

July 21, 2008 23:18
 

Mark Monforti said:

I hate aliases.  Especially one letter Aliases.   If you thing the table might change then fine use an alias.   Otherwize its just lazy code writing because of the lack of intellesense.  That being said if someone tells me that my code will execute faster because of it I would go to aliases.  

August 14, 2008 20:42
 

Mark Monforti said:

Oh and another problem I just had with aliases.

One SP has two tables aliased as c and p presumably for current and previous.  Then the next SP has the same two tables as t and l for apperently for this year and last year and then still a third SP has the two tables aliased as p and o for present and old.  So now p could be either table depending on what SP you are in.

If you are going to alias you have to have a lookup sheet and make sure that the six people you have working on your project are aliasing the same.  

August 14, 2008 20:48
 

Sid Atkinson Jr. said:

Why use aliases? SSMS 2008 gives you good reason..

August 17, 2008 16:43
 

Bookmarks about Sql said:

October 27, 2008 12:00

Leave a Comment

(required) 
(optional)
(required) 
Submit

This Blog

Syndication

News

Powered by Community Server (Personal Edition), by Telligent Systems