Should I Always Fully Qualify Column Names In SQL? - sql

Out of interest when working with SQL statements should I always use the fully qualifed column name (tablename.columnname) even if only working with one table e.g.
SELECT table.column1, table.column2 FROM table

It's better if you do - it doesn't add any complexity, and it can prevent errors in the future.
But in a well-defined system, you shouldn't have to - it's like namespaces in programming languages. The ideal is not to have conflicts, but it can clutter the code with the superfluous use of explicit names.
-Adam

I generally follow these rules:
When using a single table, it is not necessary to use the table name prefix:
SELECT col1, col2 FROM table1
For multiple tables, use the full table name. Aliases can be confusing, especially when doing multiple joins:
SELECT table1.col1, table2.col2 FROM table1 INNER JOIN table2 on
table1.id = table2.id
I see many developers using table aliases, but particularly in large projects with multiple developers, these can become cryptic. A few extra keystrokes can provide a lot more clarity in the code.
If may, however, become necessary to use a column alias when columns have the same name. In that case:
SELECT table1.col1, table2.col1 as table2_col1 FROM table1
INNER JOIN table2 on
table1.id = table2.id

I would put this as personal preference. It would only make a difference if you started joining tables which contain duplicate column names.
Also, rather than write out the table name in full, use an alias:
SELECT t.column1, t.column2 FROM table as t

If you are only selecting from one table I do not see the overall usefulness. If you are selecting from multiple tables, qualifying the column names would certainly make it easier to read for any other developer who may not be familiar with your database schema.

If you're only querying one table - I'd say no. It's more readable that way.

Don't solve problems you don't have yet. (At least that's what my team lead is always telling me.) I'm sure the monkey who someday has to add a JOIN to your statement can figure it out.

I think it is a good idea to always use the fully qualified column name. Use an alias if the table name is too long. It also prepares your queries for futures additions of e.g. joins.

I would say it is nice to use qualified name, it adds readability to your code. It does not make much sense to use it for single table but for multiple tables it is must. if table names are too big then it is recommended to use alias, alias should preferably be derived from table name.
SELECT Dep.Name,Emp.Name
FROM Department DEP INNER JOIN Employee Emp
ON Dep.departmentid=Emp.DepartmentID

No.
You should always alias the tables, and you should always qualify your column names with the table aliases.
select
p.FirstName,
p.LastName,
p.SSN
from Person p
where p.ID = 345

I prefer to use a table alias when more than 1 table is in play.

Even the most well defined systems are subject to change. A new field could quite easily be introduced to a table causing ambiguity in an existing query.
Fully qualifying them protects you from this scenario.

Related

cannot implement this inner join in oracle

I have recently started to learn oracle, and I am having difficulty understanding this inner join on the tables.
INSERT INTO temp_bill_pay_ft
SELECT DISTINCT
ft.ft_id,
ft.ft_credit_acct_no,
ft.ft_debit_acct_no,
ft.ft_stmt_nos,
ft.ft_debit_their_ref,
ft.ft_date_time
FROM
funds_transfer_his ft
INNER JOIN temp_bill_pay_lwday_pl dt
ON ft.ft_id = dt.ac_ste_trans_reference || ';1'
AND ft.ft_credit_acct_no = dt.ac_id;
It is this line specifically which I dont understand, why do we use || here, I suppose it is for concatenation.
ON ft.ft_id = dt.ac_ste_trans_reference||';1'
Can somebody please explain to me this sql query. I would really appreciate it. Thank you.
This is string concatenation. The need is because there is a design error in the database and join keys are not the same in the two tables. So the data might look something like this:
ft_id ac_ste_trans_reference
123;1 123
abc;1 abc
In order for the join to work, the keys need to match. One possibility is to remove the last two characters from ft_id, but I'm guessing those are meaningful.
I can speculate on why this is so. One possibility is that ft_id is really a compound key combined into a single column -- and the 1 is used to indicate the "type" of key. If so, then there are possibly other values after this:
ft_id
123;1
garbled;2
special;3
The "2" and "3" would refer to other reference tables.
If this is the situation, then it would be cleaner to have a separate column with the correct ac_ste_trans_reference. However that occupies additional space, and can require multiple additional columns for each type. So hacks like the one you see are sometimes implemented.
Yes it is used for concatenation.
But only somebody having worked on this database model can explain what table data represent and why this concatenation is needed for this joining condition.

Querying Table vs Querying Subquery of Same Table

I'm working with some very old legacy code, and I've seen a few queries that are structured like this
SELECT
FieldA,
FieldB,
FieldC
FROM
(
SELECT * FROM TABLE1
)
LEFT JOIN TABLE2 ON...
Is there any advantage to writing a query this way?
This is in Oracle.
There would seem to be no advantage to using a subquery like this. The reason may be a historical relic, regarding the code.
Perhaps once upon a time, there was a more complicated query there. The query was replaced by a table/view, and the author simply left the original structure.
Similarly, once upon a time, perhaps a column needed to be calculated (say for the outer query or select). This column was then included in the table/view, but the structure remained.
I'm pretty sure that Oracle is smart enough to ignore the subquery when optimizing the query. Not all databases are that smart, but you might want to clean-up the code. At the very least, such as subquery looks awkward.
As a basic good practice in SQL, you should not code a full-scan from a table (SELECT * FROM table, without a WHERE clause), unless necessary, for performance issues.
In this case, it's not necessary: The same result can be obtained by:
SELECT
Fields
FROM
TABLE1 LEFT JOIN TABLE2 ON...

Difference between SQL Server codes?

For a school assignment, I have to create a database and run reports. I've created code and a classmate has also created code and it runs the same thing, but his is in a format I've not seen and don't quite understand.
Here is mine:
SELECT
Course.Name AS 'Course Name',
Program.Name AS 'Program Name'
FROM
Course, Program, ProgramCourse
WHERE
ProgramCourse.CourseID = Course.ID
AND
ProgramCourse.ProgramID = Program.ID
GO
And here's his:
CREATE VIEW NumberOfCoursePerProgram AS
SELECT
p.name AS ProgramName,
c.name AS CourseName
FROM
Program p
JOIN
ProgramCourse pc ON pc.ProgramID = p.ID
JOIN
Course c ON c.ID = pc.CourseID
GO
I ran both queries using the data in the tables I've created. They return practically the same results, just in a slightly different order but it fulfills the assignment question. Anyway, if I delete the p from Program p from his code, it returns an error
The multi-part identifier "p.name" could not be bound.
So how is SQL Server able to accept p.name and p.ID, etc. when I haven't ever established these variables? I don't quite understand how the code is working on his. Mine seems simple and straightforward, and I definitely understand what's going on there. So can someone explain his?
Thanks
There's a few differences. First off, he's creating a VIEW rather than just a select statement:
CREATE VIEW NumberOfCoursePerProgram AS
Once the view is created, you can query the view just as you would a table:
SELECT * FROM NumberOfCoursePerProgram;
Second, he's using an ANSI JOIN rather than an implicit JOIN. His method is more modern and most likely considered more correct by today's standards:
JOIN ProgramCourse pc ON pc.ProgramID = p.ID
JOIN Course c ON c.ID= pc.CourseID
Rather than:
FROM Course, Program, ProgramCourse
Also, note he's assigning table aliases when he refers to a table:
FROM Program p
The p at the end allows you to substitute p rather than specify the entire table name of Program elsewhere in the query. For example, you can now say WHERE p.Foo > 5 rather than WHERE Program.Foo > 5. In this case, it's just a shortcut and saves a few characters. However, suppose you were referring to the same table twice (for example, JOINing in two different rows on the same table). In that case, you might have to provide aliases for each table to disambiguate which one is which.
These are called alias in SQL. Alias is basically created to give more readability and for better ease of writing code.
The readability of a SELECT statement can be improved by giving a
table an alias, also known as a correlation name or range variable. A
table alias can be assigned either with or without the AS keyword:
table_name AS table alias
table_name table_alias
So in your query p is an alias to Program so that means now you can refer your table Program by the name of p instead of writing the whole name Program everywhere.
Similarly you can access the names of the columns of your table Program by simply writing p with a dot and then the column name. Something like p.column. This technique is very useful when you using JOINS and some your tables have similar names of the columns.
EDIT:-
Although most of the points are covered in other's answer. I am just adding a point that you should avoid the habit of JOINING table the way you are doing it right now.
You may check Bad habits to kick : using old-style JOINs by Aaron Bertrand for reference.
CREATE VIEW NumberOfCoursePerProgram AS
BEGIN
SELECT
p.name AS ProgramName,
c.name AS CourseName
FROM
Program p
JOIN
ProgramCourse pc ON pc.ProgramID= p.ID
JOIN Course c ON c.ID= pc.CourseID
END
GO
Observe that both tables Program and Course have a table alias defined.
The select part must specify the table from which the column name comes from. Which is exactly what you did. Your partner just added aliases to the tables names. These aliases are shorter, and makes the query look a bit less like a big wall of text.
The other difference is the use of joints. The joins are usually used to link results from two tables that has a corresponding column.
The columns are usually the primary key, and the foreign key in the second table.
Your query is fine, but the join syntax is preferred.
Edit : Once the view is created, it is now compiled and can be used in a select just like a table.
SELECT * FROM NumberOfCoursePerProgram
If you need to modify the view, you can use
ALTER VIEW NumberOfCoursePerProgram AS
......
......
There are a few things going on here:
if I delete the "p" from "Program p" from his code, it returns "The multi-part identifier "p.name" could not be bound."
The P is an alias for program. By doing it that way. If you ever need to use Program you can just call it P.
As far as what he is doing: it's better to do a JOIN in this case as opposed to doing a multi-table SELECT that you are doing. In simple cases it doesn't really matter but what if course and program both had millions of rows. In your way you are basically selecting everything. By doing the join on ProgramID you are only getting those items in ProgramCourse that correspond to an entry in Program as well (tied together by ID and CourseID).
One more important note. You are doing a simple SELECT statement. In SQL there are objects called VIEWS that act as a virtual table. He can now do any time a SELECT * FROM NumberOfCoursePerProgram and he will never have to do any of the joins, and selects again.
Hope that helps...
In SQL Server you can give a table an alias without AS, its optional.
If you were to add the AS it would will work just like you have it.
It may also be worthy to note that he is using a join as opposed to a where clause join, which is my preference because it's easier to read and more update code ethic.
Sometimes you need to join on a WHERE clause because of multiple conditions on join, but that's pretty rare in your case.

comparing a column with itself in WHERE clause of oracle SELECT

I have a multi-table SELECT query which compares column values with itself like below:
SELECT * FROM table1 t1,table2 t2
WHERE t1.col1=t2.col1 --Different tables,So OK.
AND t1.col1=t1.col1 --Same tables??
AND t2.col1=t2.col1 --Same tables??
This seems redundant to me.
My query is, Will removing them have any impact on logic/performance?
Thanks in advance.
This seems redundant, its only effect is removing lines that have NULL values in these columns. Make sure the columns are NOT NULL before removing those clauses.
If the columns are nullable you can safely replace these lines with (easier to read, easier to maintain):
AND t1.col1 IS NOT NULL
AND t2.col1 IS NOT NULL
Update following Jeffrey's comment
You're absolutely right, I don't know how I didn't see it myself: the join condition t1.col1=t2.col1 implies that only the rows with the join columns not null will be considered. The clauses tx.col1=tx.col1 are therefore completely redundant and can be safely removed.
Don't remove them until you understand the impact. If, as others are pointing out, they have no effect on the query and are probably optimised out, there's no harm in leaving them there but there may be harm in removing them.
Don't try to fix something that's working until your damn sure you're not breaking something else.
The reason I mention this is because we inherited a legacy reporting application that had exactly this construct, along the lines of:
where id = id
And, being a sensible fellow, I ditched it, only to discover that the database engine wasn't the only thing using the query.
It first went through a pre-processor which extracted every column that existed in a where clause and ensured they were indexed. Basically an auto-tuning database.
Well, imagine our surprise on the next iteration when the database slowed to a fraction of its former speed when users were doing ad-hoc queries on the id field :-)
Turns out this was a kludge put in by the previous support team to ensure common ad-hoc queries were using indexed columns as well, even though none of our standard queries did so.
So, I'm not saying you can't do it, just suggesting that it might be a good idea to understand why it was put in first.
Yes, the conditions are obviously redundant since they're identical!
SELECT * FROM table1 t1,table2 t2
WHERE t1.col1=t2.col1
But you do need at least one of them. Otherwise, you'd have a cartesian join on your hands: each row from table1 will be joined to every row in table2. If table1 had 100 rows, and table2 had 1,000 rows, the resultant query would return 100,000 results.
SELECT * FROM table1 t1,table2 t2 --warning!

Is there a way to rename a similarly named column from two tables when performing a join?

I have two tables that I am joining with the following query...
select *
from Partners p
inner join OrganizationMembers om on p.ParID = om.OrganizationId
where om.EmailAddress = 'my_email#address.com'
and om.deleted = 0
Which works great but some of the columns from Partners I want to be replaced with similarly named columns from OrganizationMembers. The number of columns I want to replace in the joined table are very few, shouldn't be more than 3.
It is possible to get the result I want by selectively choosing the columns I want in the resulting join like so...
select om.MemberID,
p.ParID,
p.Levelz,
p.encryptedSecureToken,
p.PartnerGroupName,
om.EmailAddress,
om.FirstName,
om.LastName
from Partners p
inner join OrganizationMembers om on p.ParID = om.OrganizationId
where om.EmailAddress = 'my_email#address.com'
and om.deleted = 0
But this creates a very long sequence of select p.a, p.b, p.c, p.d, ... etc ... which I am trying to avoid.
In summary I am trying to get several columns from the Partners table and up to 3 columns from the OrganizationMembers table without having a long column specification sequence at the beginning of the query. Is it possible or am I just dreaming?
select om.MemberID as mem
Use th AS keyword. This is called aliasing.
You are dreaming in your implementation.
Also, as a best practice, select * is something that is typically frowned upon by DBA's.
If you want to limit the results or change anything you must explicitly name the results, as a potential "stop gap you could do something like this.
SELECT p.*, om.MemberId, etc..
But this ONLY works if you want ALL columns from the first table, and then selected items.
Try this:
p.*,
om.EmailAddress,
om.FirstName,
om.LastName
You should never use * though. Always specifying the columns you actually need makes it easier to find out what happens.
But this creates a very long sequence
of select p.a, p.b, p.c, p.d, ... etc
... which I am trying to avoid.
Don't avoid it. Embrace it!
There are lots of reasons why it's best practice to explicity list the desired columns.
It's easier to do searches for where a particular column is being used.
The behavior of the query is more obvious to someone who is trying to maintain it.
Adding a column to the table won't automatically change the behavior of your query.
Removing a column from the table will break your query earlier, making bugs appear closer to the source, and easier to find and fix.
And anything that uses the query is going to have to list all the columns anyway, so there's no point being lazy about it!