How to Add Column at Specific Location in Table? – Interview Question of the Week #126

Interview question: How do you add a column at a specific location in a SQL Server table?

Ceramic vessels stay in one shelf order but are arranged differently for display

Answer: ALTER TABLE ... ADD appends the new column to the table definition. If you want a different display order, name the columns in that order in SELECT. Changing the table definition’s ordinal position requires rebuilding the table and is usually unnecessary.

I have heard three reasons for wanting a column in the middle. They sound persuasive until we separate how a table is defined from how a result is presented.

The Result Looks Wrong With SELECT *

Yes, SELECT * shows columns in the table definition’s order, and adding a column puts it at the end. But an application or report should ask for the columns it needs, in the order it wants them:

-- Open a fresh query window; do not replace an existing temporary table.
IF OBJECT_ID(N'tempdb..#Orders') IS NOT NULL
    THROW 50126, 'Temporary demo table exists. Open a fresh window.', 1;
CREATE TABLE #Orders (OrderId int, Quantity int);
INSERT INTO #Orders (OrderId, Quantity) VALUES (1, 3);
ALTER TABLE #Orders ADD Note nvarchar(100) NULL;
SELECT OrderId, Note, Quantity
FROM #Orders;
DROP TABLE #Orders;
OrderId, Note, Quantity are displayed in the SELECT list order, with Note NULL
The SELECT list decides the order: OrderId, Note, Quantity. Note was added last and is NULL in this row.

Note was added last, yet it appears between the other two columns in the result. Naming columns also prevents a later schema change from unexpectedly altering an application’s SELECT * result shape.

The Table Looks Untidy in the Designer

I understand the desire to group related columns visually. That preference alone rarely justifies rebuilding a populated table. Re-creating it can affect dependencies, permissions, metadata and downtime. SQL Server Management Studio blocks that sort of designer change by default for a reason. Keep the definition stable and order columns in the query or report where the order matters.

Adjacent Columns Must Make a Query Faster

I once compared this claim to saying that learning to swim helps you drink water. Both topics involve water, but one doesn’t follow from the other. Likewise, two columns appearing next to each other in a result doesn’t make a query faster. Check the actual plan, reads, indexes and predicates when performance is the concern. A deliberate index can matter far more than the table designer’s visual column sequence.

There can be specialized storage and row-layout considerations when a table is redesigned. Those need measured evidence for a real workload, not a blanket rule to move two frequently selected columns side by side.

Column order: Where should the order live?

Column order is not a table problem, it is a SELECT list choice, so name your columns.

Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.


Discover more from SQL Authority with Pinal Dave

Subscribe to get the latest posts sent to your email.

SQL Server, SQL Server Management Studio
Previous Post
How to Round Up or Round Down Number in SQL Server? – Interview Question of the Week #125
Next Post
How to Write Case Statement in WHERE Clause? – Interview Question of the Week #127

Related Posts

6 Comments. Leave new

  • Carlo Borreo
    June 12, 2017 8:48 pm

    I am not satisfied of your solution 2.
    Yes, you are right, but sometimes you want a select * to return something beautiful, with all the things where you expect them. Yes, this is irrational :-)
    But when you have some serious downtime available, you can still copy all data to a new table, delete the old one and rename the new to replace the old. Of course, FK must also be taken care of.

    Reply
  • I understand and appreciate the answers and commentary to the question presented in this article (and mostly agree). But I think the real answer should be: “You can’t, unless you recreate the table with the new column and migrate the data.” Followed by the commentary above and additional points on why recreating the table is, generally speaking, probably a bad practice.

    Love the blog!

    Reply
  • I get what you are saying in THEORY, but in PRACTICE I dIsagree. When doing interactive data analysis on tables with a large number of columns, I find that SELECT * is useful when you may not know which column has the data you are looking for. Keeping columns logically grouped/ordered is helpful. If you want to see an example of a mess caused by the inability to place columns in logical order, look at MS Dynamics CRM tables.

    Ideally, SQL Server would have a clause in the ALTER TABLE statement like Informix SQL has (I used Informix in past life).

    It was basically of the format: ALTER TABLE tablename ADD newcolumn TYPE BEFORE existingcolumn

    Reply
  • I agree with Mark’s comment regarding the correct answer to this question.
    I also think the theoretical reasons for SQL behaving this way should have been pointed out. Namely, SQLs origins in Relational Database Theory.
    A table in SQL is a set, with every row being an element of that set.
    Each element has attributes that apply to that specific element.
    The attributes in SQL are columns.

    When you want a specific element, for example Customer, it’s meaningful to talk about the Name, or Address.
    It’s not meaningful to say give me all Customer’s where [Attribute 9] contains Texas.
    That’s not a RDBMS, that’s a list.
    It goes to the heart of SQL that the columns of an row have no order.
    See first paragraph https://en.wikipedia.org/wiki/Relation_(database)

    Reply
  • I’m firmly in the camp of never relying on the ordinal position of the columns for anything. But playing devil’s advocate, you could also create a view which can be altered at any time (thus also altering the ordinal of each returned column.

    Reply
  • Totally disagree. What about using nice way to copy table structure using {select top 0 * into [#mytbl] from [mytable]}? What about replacing totally hardcoded unpivot structure to transform columns to rows using xml and *? You must hardcode all columns, right? So, you need rewrite your code after table columns updated? No. Just use xml with * instead of hardcody unpivots. What about programmability comfort, when you have large set of colums, but, theyre related logically? Code readability does not matter? What about adding column after rowversion column, and before it? Hudge, hudge difference!

    So, my opinion is: wrong answer, no job. Right answer is: you need recreate table, if adding column to not last position. And please comfortably, but with arguments use *. And using normal forms to infinity is waste of time and code readability. Need to keep smart balance here.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.