加入时-返回两列

时间:2019-06-21 14:51:18

标签: sql sql-server tsql

我做了一个加入声明:

SELECT * 
FROM dbo.table1 a
JOIN dbo.table2 b ON a.[columnX] = b.[columnY]

结果中,我有两列,表1中的columnX和表2中的columnY。试图将列重命名为相同的名称,但是发生了相同的事情。对于来自Oracle的我来说,这很奇怪,因为join语句实际上应该在该特定列上连接表,不是吗?

如何编写联接以使两列中只有一列?

编辑:是的,我知道*返回所有列。如果不是那么明显,那就是我想要的。这就是为什么我使用*的原因,令人惊讶。问题是关于如何保留重复项之一。您可能会不断收获*将返回所有内容1000次,如果没有正确的答案或建议,将毫无帮助。

3 个答案:

答案 0 :(得分:1)

您的SELECT *意味着返回FROMJOIN表中引用的所有表中的所有列。

相当于:

SELECT table1.*, table2.*
FROM table1 
JOIN table2
ON table1.columnX = table2.columnY

因此,只需将SELECT更改为您的显式列即可:

SELECT table1.columnX
FROM table1 
JOIN table2
ON table1.columnX = table2.columnY

答案 1 :(得分:1)

您需要指定要返回的字段。 SELECT *将为您提供两个表中的所有字段(包括JOIN中列出的两个字段)。 对每个字段使用以下逻辑,并排除您不希望返回的任何字段。

我还为您的表赋予了别名,以使列名更易于理解。

    SELECT
     t1.[columnA]
    ,t1.[columnB]
    ,t1.[columnC]
    .
    .
    .
    ,t2.[columnA]
    ,t2.[columnB]
    ,t2.[columnC]
    FROM dbo.table1 t1
    INNER JOIN dbo.table2 t2 ON t1.[columnX] = t2.[columnY]

如果您真的不想列出所有列,则可以选择SELECT * INTO TEMP TABLE,从TEMP表中删除不需要的列,然后从TEMP表中删除SELECT *,在此找到( http://stackoverflow.com/questions/729197/sql-exclude-a-column-using-select-except-columna-from-tablea),我将在下面添加通用脚本,以防链接消失,并带有特定链接以使您的表与联接匹配。

尽管这可以工作,但我建议仅使用SELECT *进行快速动态检查,如果这是过程或视图的一部分或其他进程使用的东西,则SELECT *可能会导致连锁问题/失败如果源表的结构发生更改,并且该过程中的后续步骤不希望发生新的更改。例如一个字段从源中删除,视图不再作为SELECT *的一部分使用,并且过程将失败,因为它期望它是INSERT任务的一部分。

我自己的经验法则是始终在查询中确定我想要的列,而不是即时数据检查。

语法的通用版本;

    /* Get the data into a temp table */
    SELECT * INTO #TempTable
    FROM YourTable
    /* Drop the columns that are not needed */
    ALTER TABLE #TempTable
    DROP COLUMN ColumnToDrop
    /* Get results and drop temp table */
    SELECT * FROM #TempTable
    DROP TABLE #TempTable

可通过联接表满足您需求的自定义版本;

    /* Get the data into a temp table */
    SELECT * INTO #TempTable
    FROM [dbo].[table1] a
    JOIN [dbo].[table2] b ON a.[columnX] = b.[columnY]
    /* Drop the columns that are not needed */
    ALTER TABLE #TempTable
    DROP COLUMN [columnX]
    /* Get results and drop temp table */
    SELECT * FROM #TempTable
    DROP TABLE #TempTable

我在与上面相同的链接上找到了一种更优雅的方法,您可以在下面的内容中动态选择SELECT *(同样,我也不宽容SELECT *);

    declare @cols varchar(max), @query varchar(max);
    SELECT  @cols = STUFF
        (
            ( 
                SELECT DISTINCT '], [' + name
                FROM sys.columns
                where object_id = (
                    select top 1 object_id from sys.objects
                    where name = 'MyTable'
                )
                and name not in ('ColumnIDontWant1', 'ColumnIDontWant2')
                FOR XML PATH('')
            ), 1, 2, ''
        ) + ']';

    SELECT @query = 'select ' + @cols + ' from MyTable';  
    EXEC (@query);

答案 2 :(得分:1)

我认为您正在寻找的是这个

select  a.* 
from    dbo.table1 a
JOIN    dbo.table2 b
        ON a.[columnX] = b.[columnY]

此语句将返回table1中联接条件为true的所有列,即table1中columnx = columny的所有记录。