104

If I'm adding a column to a table in Microsoft SQL Server, can I control where the column is displayed logically in queries?

I don't want to mess with the physical layout of columns on disk, but I would like to logically group columns together when possible so that tools like SQL Server Management Studio list the contents of the table in a convenient way.

I know that I can do this through SQL Management Studio by going into their "design" mode for tables and dragging the order of columns around, but I'd like to be able to do it in raw SQL so that I can perform the ordering scripted from the command line.

ConcernedOfTunbridgeWells
  • 64,444
  • 15
  • 143
  • 197
fastcall
  • 2,564
  • 4
  • 20
  • 21
  • Too late for an answer but have a look at this link. http://blog.sqlauthority.com/2013/03/11/sql-server-how-to-add-column-at-specific-location-in-table/ – sqluser Jan 15 '15 at 23:43
  • see also http://stackoverflow.com/questions/4402312/why-cant-i-reorder-my-sql-server-columns and http://stackoverflow.com/questions/5327545/adding-column-between-two-other-columns-in-sql-server – Tim Abell Aug 06 '15 at 18:12
  • more related things: http://stackoverflow.com/questions/34818/sql-server-does-column-order-matter and http://dba.stackexchange.com/questions/18719/does-the-order-of-columns-in-a-tables-definition-matter – Tim Abell Aug 06 '15 at 18:15
  • and another related question, about whether it matters http://stackoverflow.com/questions/6692021/performance-space-implications-when-ordering-sql-server-columns – Tim Abell Aug 06 '15 at 18:20
  • [microsoft connect: ALTER TABLE syntax for changing column order](https://connect.microsoft.com/SQLServer/Feedback/Details/739788) - response is of the chocolate-teapot variety as usual WONTFIX – Tim Abell Aug 06 '15 at 20:43

9 Answers9

85

You can not do this programatically (in a safe way that is) without creating a new table.

What Enterprise Manager does when you commit a reordering is to create a new table, move the data and then delete the old table and rename the new table to the existing name.

If you want your columns in a particular order/grouping without altering their physical order, you can create a view which can be whatever you desire.

vzczc
  • 9,270
  • 5
  • 52
  • 61
48

I think what everyone here is missing is that although not everyone has to deal with 10's, 20's, or 1000's instances of the same software system installed throughout the country and world, those of us that design commercially sold software do so. As a result, we expand systems over time, expand tables by adding fields as new capability is needed, and as those fields are identified do belong in an existing table, and as such, over a decade of expanding, growing, adding fields, etc to tables, and then having to work with those tables from design, to support, to sometimes digging into raw data/troubleshooting to debug new functionality bugs, it is incredibly aggravating to not have the primary information you want to see within the first handful of fields, when you may have tables with 30, 40, 50, or even 90 fields, and yes, in a strictly normalized database.

I've often wished I could do this, for this exact reason. But short of doing exactly what SQL does, building a Create Script for a new Table the way I want it, writing the Insert to it, then dropping all existing constraints, relationships, keys, index, etc etc from the existing table and renaming the "new" table back to the old name, and then reading all those keys, relationships, index, etc etc ....

It's not only tedious, time-consuming, but ... in five more years, it will need to happen again.

It's so close to worth that massive amount of work, however the point is, it won't be the last time we need this ability, since our systems will continue to grow, expand, and get fields in a wacked ordered driven by need/design additions.

A majority of developers think from a single system standpoint that serves a single company or very specific hard box market.

The "off-the-shelf" but significantly progressive designers and leaders of development in their market space will always have to deal with this problem, over and over, and would love a creative solution if anyone has one. This could easily save my company a dozen hours a week, just not having to scroll over, or remember where "that" field is in the source data table.

Pang
  • 9,564
  • 146
  • 81
  • 122
Philip Coyner
  • 481
  • 4
  • 2
  • 1
    We had the same issue and created a stored procedure that automates this process (rename, create new table, copy, recreate all foreign keys, constraints, etc.). You only need to pass in the tablename and the new order of columns. If this could actually save your company dozens of hours a week, you should invest the time of writing a similar script. For us, it took only about a 2-3 days to have a stable script that we use routinely to reorder columns. It takes care of all features we use in SqlServer (e.g. partial indexes, indexed views, etc) and consists of only about 400 LOC. – Andreas Sep 02 '16 at 14:31
  • 5
    I don't know why they can't abstract away the column layout somehow. It doesn't have to physically reorder the columns! The amount of PHD level and beyond engineering in Sql Server is truly astonishing. When you consider the complexity of query plan generation, the statistics, the indexing and nobody has stood up yet and said 'Lets just make a table that represents LOGICAL order. `FieldID Guid`, `OrderBy int`. Done. Then SSMS or `SELECT *` uses that. Turn it off if you're a perfect DBA and don't want it. Very frustrating. And now my tables are big enough that I can't brute force it anymore. – Simon_Weaver Feb 03 '19 at 17:53
  • I know this is an old comment, but visual studio within database project automatically create SQL script for physical column reorder when you change schema of the table and hit publish. – Muflix Aug 31 '20 at 19:25
  • 1
    All this really needs isn't any kind of fundamental change to the engine: we just need Microsoft to declare a well-known _Extended Property_ name for logical column ordering, and have SSMS and other tooling start to respect that XP when displaying columns in editors/designers. [I've filed a SQL Server feature request for this - if enough people upvote it then they'll eventually have to stop ignoring it](https://feedback.azure.com/d365community/idea/ff4becca-c1b3-ec11-a81c-6045bd7d1bee) :) – Dai Apr 04 '22 at 02:50
6

When Management Studio does it, it's creating a temporary table, copying everything across, dropping your original table and renaming the temporary table. There's no simple equivalent T-SQL statement.

If you don't fancy doing that, you could always create a view of the table with the columns in the order you'd like and use that?

Edit: beaten!

tags2k
  • 82,117
  • 31
  • 79
  • 106
5

If I understand your question, you want to affect what columns are returned first, second, third, etc in existing queries, right?

If all of your queries are written with SELECT * FROM TABLE - then they will show up in the output as they are laid out in SQL.

If your queries are written with SELECT Field1, Field2 FROM TABLE - then the order they are laid out in SQL does not matter.

N00b Pr0grammer
  • 4,503
  • 5
  • 32
  • 46
Otto
  • 2,083
  • 3
  • 19
  • 17
1

There is one way, but its only temporarily for the query itself. For example,

Lets say you have 5 tables. Table is called T_Testing

FirstName, LastName, PhoneNumber, Email, and Member_ID

you want it to list their ID, then Last Name, then FirstName, then Phone then Email.

You can do it as per the Select.

Select Member_ID, LastName, FirstName, PhoneNumber, Email
From T_Testing

Other than that, if you just want the LastName to Show before first name for some reason, you can do it also as follows:

Select LastName, *
From T_Testing

The only thing you wanna be sure that you do is that the OrderBy or Where Function needs to be denoted as Table.Column if you are going to be using a Where or OrderBy

Example:

Select LastName, *
From T_Testing
Order By T_Testing.LastName Desc

I hope this helps, I figured it out because I needed to do this myself.

Markus Safar
  • 6,324
  • 5
  • 28
  • 44
Steven
  • 11
  • 1
1
  1. Script your existing table to a query window.
  2. Run this script against a Test database (remove the Use statement)
  3. Use SSMS to make the column changes you need
  4. Click Generate Change Script (left most and bottommost icon on the buttonbar, by default)
  5. Use this script against your real table

All the script really does is create a second table table with the desired column orders, copies all your data into it, drops the original table and then renames the secondary table to take its place. This does save you writing it yourself though should you want a deploy script.

Paul
  • 1,041
  • 11
  • 26
1

It is not possible to change the order of the columns without recreating the whole table. If you have a few instances of the database only, you can use SSMS for this (Select the table and click "design").

In case you have too many instances for a manual process, you should try this script: https://github.com/Epaminaidos/reorder-columns

Andreas
  • 1,997
  • 21
  • 35
1
  1. Open your table in SSMS in design mode:

    Table in SSMS in design mode

  2. Reorder your columns:

    Table in SSMS in design mode with new column

    It is important to not save your change.

  3. Click the "Generate Change Script" button:

    Generate Change Script button

  4. Now a window will open that contains the script to apply this change:

    Generated script

    Copy the text from the window.

In this instance, it generated the following code:

/* To prevent any potential data loss issues, you should review this script in detail before running it outside the context of the database designer.*/
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Tmp_MyTable
    (
    Id int NOT NULL,
    Name nvarchar(30) NULL,
    Country nvarchar(50) NOT NULL
    )  ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_MyTable SET (LOCK_ESCALATION = TABLE)
GO
IF EXISTS(SELECT * FROM dbo.MyTable)
     EXEC('INSERT INTO dbo.Tmp_MyTable (Id, Name, Country)
        SELECT Id, Name, Country FROM dbo.MyTable WITH (HOLDLOCK TABLOCKX)')
GO
DROP TABLE dbo.MyTable
GO
EXECUTE sp_rename N'dbo.Tmp_MyTable', N'MyTable', 'OBJECT' 
GO
COMMIT

As you can see, what it does is 1) create a new temporary table, 2) copy the data over to the temporary table, 3) delete the original table and 4) rename the temporary table to the original table's name.

Daniel Jonsson
  • 3,261
  • 5
  • 45
  • 66
0

It can be done using SQL, by modifying the system tables directly. For example, look here:

Alter table - Add new column in between

However, I would not recommend playing with system tables, unless it's absolutely necessary.

Milan Babuškov
  • 59,775
  • 49
  • 126
  • 179