Alternatives to USING in a JOIN for SQL Server for avoiding duplicated columns in joined table

前端 未结 4 2019
情歌与酒
情歌与酒 2020-12-22 12:02

SQL Server does not offer the keyword USING in the context of a JOIN,
nor it provides a NATURAL JOIN.

Besides explicitly (manually) listing all the columns (link

4条回答
  •  南笙
    南笙 (楼主)
    2020-12-22 12:21

    It is not easy. But it is possible. Developing from this, you would first create two separated lists with all the columns of the 2 tables, excluding the common column on which you want to join:

    DECLARE @columnsA varchar(8000)
    
    SELECT @columnsA = ISNULL(@columnsA + ', ','') + QUOTENAME(column_name)
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME = 'tableA' AND COLUMN_NAME <> 'commonColumn'
    ORDER BY ORDINAL_POSITION
    
    DECLARE @columnsB varchar(8000)
    
    SELECT @columnsB = ISNULL(@columnsB + ', ','') + QUOTENAME(column_name)
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME = 'tableB' AND COLUMN_NAME <> 'commonColumn'
    ORDER BY ORDINAL_POSITION
    

    Then you would use them for your query, selecting the commonColumn only for one of the table:

    EXEC ('SELECT tableA.commonColumn, ' + @columnA + ', ' + @columnsB + ' FROM tableA INNER JOIN tableB ON tableA.commonColumn = tableB.commonColumn;')
    

    So there's at least one way to do it. :) It is apparently also moderately efficient. I am not an SQL expert, but I suppose there is a way to create a function out of this, maybe one function to "select all columns but [...]" and one function that would do the join as USING would do.


    It becomes a little bit simpler if in listing we add also the containing table. In this way we need to extract only the column names from one table.

    DECLARE @columnsB varchar(8000)
    
    SELECT @columnsB = ISNULL(@columnsB + ', ','') + QUOTENAME(table_name) + '.' + QUOTENAME(column_name)
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME = 'tableB' AND COLUMN_NAME <> 'commonColumn'
    ORDER BY ORDINAL_POSITION
    

    And the query is modified into:

    EXEC ('SELECT tableA.* ', ' + @columnsB + ' FROM tableA INNER JOIN tableB ON tableA.commonColumn = tableB.commonColumn;')
    

提交回复
热议问题