reformed
reformed

Reputation: 4780

How to work with data in dynamically created column in SQL Server?

Sometimes you want to append a string or int to the data in a given column, such as SELECT 1005 + ID FROM Users (where you'd be adding 1005 to the ID column data). How can this be done for columns that are created dynamically?

The following works:

SELECT ID,
       Name,
       (SELECT Email FROM Emails WHERE Emails.ID = d.ID) AS Email,
       Address
FROM data d

But adding the following new line creates the error Invalid column name "Email":

SELECT ID,
       Name,
       (SELECT Email FROM Emails WHERE Emails.ID = d.ID) AS Email,
       Email + ' testing ' AS Test, /* New line that causes error */
       Address
FROM data d

How to fix this error?

Upvotes: 0

Views: 467

Answers (3)

Aaron Bertrand
Aaron Bertrand

Reputation: 280252

You can't reference an alias. You can repeat the expression (usually unwise performance-wise and/or undesirable syntax-wise) or use a subquery / CTE. And why are you using a correlated subquery instead of a join?

SELECT ID, Name, Email, Email + ' testing' AS Test, Address
FROM
(
  SELECT d.ID, d.Name, e.Email, d.Address
  FROM dbo.data AS d
  INNER JOIN dbo.Emails AS e
  ON e.ID = d.ID
) AS x;

...or a CTE...

;WITH x AS
(
  SELECT d.ID, d.Name, e.Email, d.Address
  FROM dbo.data AS d
  INNER JOIN dbo.Emails AS e
  ON e.ID = d.ID
)
SELECT ID, Name, Email, Email + ' testing' AS Test, Address
  FROM x;

Upvotes: 3

orgtigger
orgtigger

Reputation: 4122

It looks like the problem your having is that you are trying to reference something that is 'Out of scope'. When you use a subquery in the select statement the subqueries tables are only accessible for that item. That access does not carry over to other items in the select statement. So, this should work for you (if it's ugly and it works, it's not ugly).

SELECT ID,
   Name,
   (SELECT Email FROM Emails WHERE Emails.ID = d.ID) AS Email,
   (SELECT Email FROM Emails WHERE Emails.ID = d.ID) 
      + ' testing ' AS Test, 
   Address
FROM data d

Upvotes: 0

HLGEM
HLGEM

Reputation: 96552

This is something that should not be done in a subquery, use a join instead. Correlated subqueries in genral are a poor technique as they can be performance killers and they are only rarely needed. They should be a technique of last resort not a technique of first resort.

SELECT ID,
       Name,
       Email,
       Email + ' testing ' AS Test, 
       Address
FROM data d 
JOIN Emails e ON e.ID = d.ID

If everyone won't have an email use a left join. If there are multipel email addresses then you may need some addtional criteria to filter on or you may need to use aggregae functions.

Upvotes: 1

Related Questions