определение имен столбцов из другой таблицы

#sql #sql-server

#sql #sql-сервер

Вопрос:

У меня есть 2 таблицы

Таблица 1:

 SELECT  
    "ColumnNm" ,
    "ColumnUserFriendlyNm"  
FROM table_1
  

который показывает:

 columnNm      ColumnUserFriendlyNm
key1          friendly name 1 
key2          friendly name 2 
  

в таблице 2 есть имена столбцов «key1» и «key2», и я хочу изменить эти имена столбцов на «дружественное имя 1″ и дружественное имя 2» в соответствии с ключом в таблице 1

Мне нужно, чтобы это было автоматически — поэтому, если у меня есть 1000 таких столбцов, мне не нужно переходить 1 к 1 и вручную вводить псевдоним в коде, я бы хотел, чтобы он извлекал «понятное имя» в соответствии с ключом из table_1

Ответ №1:

Если вы не создадите derived table после псевдонимирования столбцов, вам придется join использовать не дружественные имена. В вашем select вы можете alias указать столбцы, которые возвращаются в конечном наборе результатов:

Пример для alias

 SELECT  
    "ColumnNm" as [friendly name 1],
    "ColumnUserFriendlyNm" as [friendly name 2]  
FROM table_1
  

Пример для alias и использование производной таблицы

 SELECT * from (
SELECT  
    "key1" as [friendly name 1],
    "key2" as [friendly name 2]  
FROM table_2 ) as table_2_aliasd
  

https://www.sqlservertutorial.net/sql-server-basics/sql-server-alias/

Если вам нужно, чтобы alias сохранялось, рассмотрите возможность создания запроса с помощью alias к view

 create view dbo.vTable1_2
as
SELECT * from (
SELECT  
    "key1" as [friendly name 1],
    "key2" as [friendly name 2]  
FROM table_2 ) as table_2_aliasd
  

Комментарии:

1. мне нужно автоматически — у меня есть 100 таких столбцов, я не хочу идти 1 на 1 и вручную записывать псевдоним в коде

2. @Manny вам придется идти один за другим, если вы не напишете какой-нибудь динамический SQL.

3. @Manny Если вам нужны псевдонимы для всех столбцов, то представление со всеми псевдонимами является лучшим решением. Выберите из представления только те, которые вам нужны по мере необходимости. Лучше сделать все это один раз в одном месте, чем выполнять запрос за запросом.

4. @Adrian J. Moreno Я также предположил это в ответе.

5. @vvvv4d разъяснил мой комментарий, просто поддержав вас.

Ответ №2:

Весь сценарий мог бы быть таким:

 DROP TABLE IF EXISTS test;
-- this is your test table
CREATE TABLE test (
  key01 INTEGER
, key02 INTEGER
, key03 INTEGER
, key04 INTEGER
, key05 INTEGER
, key06 INTEGER
, key07 INTEGER
, key08 INTEGER
, key09 INTEGER
, key10 INTEGER
)
;
CREATE TABLE mapname (
  column_name VARCHAR(32)
, user_friendly_column_name VARCHAR(32)
);
-- this is your name mapping table ...
INSERT INTO mapname
          SELECT 'key01' , 'friendly_name_01'
UNION ALL SELECT 'key02' , 'friendly_name_02'
UNION ALL SELECT 'key03' , 'friendly_name_03'
UNION ALL SELECT 'key04' , 'friendly_name_04'
UNION ALL SELECT 'key05' , 'friendly_name_05'
UNION ALL SELECT 'key06' , 'friendly_name_06'
UNION ALL SELECT 'key07' , 'friendly_name_07'
UNION ALL SELECT 'key08' , 'friendly_name_08'
UNION ALL SELECT 'key09' , 'friendly_name_09'
UNION ALL SELECT 'key10' , 'friendly_name_10'
;

SELECT
   'SELECT sp_rename '
 '''' table_name '.' c.column_name ''''
 ' ''' user_friendly_column_name ''''
 ' ''COLUMN'';'
FROM information_schema.columns c
JOIN mapname m ON m.column_name=c.column_name
WHERE table_schema='dbo'
  AND table_name='test'
;
  

— и вы получаете :

 sp_rename 'test.key01' 'friendly_name_01' 'COLUMN';
sp_rename 'test.key02' 'friendly_name_02' 'COLUMN';
sp_rename 'test.key03' 'friendly_name_03' 'COLUMN';
sp_rename 'test.key04' 'friendly_name_04' 'COLUMN';
sp_rename 'test.key05' 'friendly_name_05' 'COLUMN';
sp_rename 'test.key06' 'friendly_name_06' 'COLUMN';
sp_rename 'test.key07' 'friendly_name_07' 'COLUMN';
sp_rename 'test.key08' 'friendly_name_08' 'COLUMN';
sp_rename 'test.key09' 'friendly_name_09' 'COLUMN';
sp_rename 'test.key10' 'friendly_name_10' 'COLUMN';
  

Ответ №3:

Мэнни, предполагая, что вы пытаетесь присвоить столбцам псевдонимы с удобным именем для запроса, а не переименовывать физические столбцы, вам нужно будет прибегнуть к динамическому SQL для этого.

Вот пример, который может помочь вам начать. Не зная вашей архитектуры данных, я позволил себе некоторую вольность ниже. Однако вы должны иметь возможность изменять эту логику для того, что вам нужно.

 /* CREATE A MOCK-UP LIST OF TABLE OBJECTS */
DECLARE @Tables TABLE ( TableNm VARCHAR(50) );
INSERT INTO @Tables VALUES ( 'Table1' ), ( 'Table2' ), ( 'Table3' );

/* CREATE A MOCK-UP OF FRIENDLY NAMES THAT TIE BACK TO THE TABLE OBJECTS */
DECLARE @FriendlyNames TABLE ( TableNm VARCHAR(50), ColumnNm VARCHAR(50), ColumnUserFriendlyName VARCHAR(50) );
INSERT INTO @FriendlyNames ( TableNm, ColumnNm, ColumnUserFriendlyName ) VALUES
    ( 'Table1', 'key1', 'Friendly Name 1' ), ( 'Table1', 'key2', 'Friendly Name 2' );

-- Create a parameter of the table name to query.
DECLARE @TableQry VARCHAR(50) = 'Table1';

-- Create a dynamic sql statement of column/aliases for the requested table.
DECLARE @dynamic_sql AS VARCHAR(MAX) = (

    SELECT
        FORMATMESSAGE ( 'SELECT %s FROM %s;', FriendlyNames.Aliases, tbls.TableNm ) AS Dsql
    FROM @Tables AS tbls
    OUTER APPLY (
    
        SELECT
            STRING_AGG ( FORMATMESSAGE ( '[%s] AS [%s]', fn.ColumnNm, fn.ColumnUserFriendlyName ), ',' ) AS Aliases
        FROM @FriendlyNames AS fn
        INNER JOIN @Tables AS tbls
            ON fn.TableNm = tbls.TableNm
    
    ) AS FriendlyNames
    WHERE
        tbls.TableNm = @TableQry

);

-- Display the dynamic SQL created.
SELECT @dynamic_sql AS DynamicSql;
  

ВОЗВРАТ

  ----------------------------------------------------------------------------- 
|                                 DynamicSql                                  |
 ----------------------------------------------------------------------------- 
| SELECT [key1] AS [Friendly Name 1],[key2] AS [Friendly Name 2] FROM Table1; |
 ----------------------------------------------------------------------------- 
  

Не делая никаких предположений о вашем опыте работы с SQL Server, для выполнения динамического SQL вы можете сделать следующее:

 -- Execute the dynamic sql.
EXEC ( @dynamic_sql );
  

Вы могли бы расширить свою таблицу удобных имен, включив в нее порядок столбцов и многое другое, но опять же, я делаю некоторые предположения о ваших потребностях, поскольку неясно, хотите ли вы на самом деле переименовать серию столбцов или сохранить список удобных имен, которые позже можно использовать для запросов.