【问题标题】:SQL to return first two columns of a tableSQL 返回表的前两列
【发布时间】:2013-04-29 08:31:22
【问题描述】:

是否有任何SQL 术语只返回表的前两个columns不知道知道字段names

有点像

SELECT Column(1), Column(2) FROM Table_Name

还是我必须先走很长一段路才能找到列名?我该怎么做?

【问题讨论】:

标签: sql sql-server-2008


【解决方案1】:

您必须先获取列名。大多数平台都支持这一点:

select column_name,ordinal_position
  from information_schema.columns
 where table_schema = ...
   and table_name = ...
   and ordinal_position <= 2

【讨论】:

  • 除了一个非常流行的名为 Oracle 的数据库管理系统
  • 由于 ordinal_position 条件,它为您提供前两列。只需更改为小于即可。
【解决方案2】:

来了

declare @select varchar(max)
set @select = 'select '

select @select=@select+COLUMN_NAME+','
from information_schema.columns
where table_name = 'TABLE' and ordinal_position <= 2

set @select=LEFT(@select,LEN(@select)-1)+' from TABLE'
exec(@select)

【讨论】:

    【解决方案3】:

    使用for xml pathdynamic query 也可以完成这项工作:

    declare @sql varchar(max)
    set @sql = (SELECT top 2 COLUMN_NAME + ',' from information_schema.columns where table_name = 'YOUR_TABLE_NAME_HERE' order by ordinal_position for xml path(''))
    set @sql = (SELECT replace(@sql +' ',', ',''))
    exec('SELECT ' + @sql + ' from YOUR_TABLE_NAME_HERE')
    

    【讨论】:

      【解决方案4】:

      不久前我写了一个存储过程来完成这项工作。即使在关系理论中没有技术列顺序 SSMS 也不是完全关系。系统存储插入列的顺序并为它们分配一个 ID。使用典型的 SELECT * 语句遵循此顺序,这就是为什么您的 SELECT 语句似乎每次都返回相同的顺序。在实践中,用任何东西 SELECT * 从来都不是一个好主意,因为它不会根据列或行锁定结果顺序。这就是说,我认为人们如此坚持“你不应该这样做”,以至于他们不会编写实际上可以做到的脚本。事实是存在可预测的系统行为,所以如果任务不是非常重要,为什么不使用它。

      这个 SPROC 当然有一些注意事项,并且是用 T-SQL 编写的,但是如果您只想返回所有具有 SELECT * 行为的值,那么这对您来说应该很容易完成。输入您的表名、列数,然后按 F5。它按照您所期望的从左到右的顺序返回它们。我将其限制为仅 5 列,但如果您需要更多,您可以编辑逻辑。接受临时表和永久表。

      EXEC OnlySomeColumns 'MyTable', 3

      /*------------------------------------------------------------------------------------------------------------------
      
          Document Title: The Unknown SELECT SPROC.sql
      
          Created By: CR
          Date: 4.28.2013
      
          Purpose: Returns all results from temp or permanent table when not knowing the column names
      
          SPROC Input Example: EXEC OnlySomeColumns 'MyTable', 3
      
      --------------------------------------------------------------------------------------------------------------------*/
      
          IF OBJECT_ID ('OnlySomeColumns', 'P') IS NOT NULL
          DROP PROCEDURE OnlySomeColumns;
      
          GO
      
              CREATE PROCEDURE OnlySomeColumns 
                      @TableName      VARCHAR (1000),
                      @TotalColumns   INT
      
          AS
      
              DECLARE @Column1        VARCHAR (1000), 
                      @Column2        VARCHAR (1000), 
                      @Column3        VARCHAR (1000), 
                      @Column4        VARCHAR (1000), 
                      @Column5        VARCHAR (1000), 
                      @SQL            VARCHAR (1000),
                      @TempTable      VARCHAR (1000),
                      @PermanentTable VARCHAR (1000),
                      @ColumnNamesAll VARCHAR (1000)
      
              --First determine if this is a temp table or permanent table
              IF @TableName     LIKE '%#%' BEGIN SET @TempTable      = @TableName END --If a temporary table
              IF @TableName NOT LIKE '%#%' BEGIN SET @PermanentTable = @TableName END --If a permanent column name
      
          SET NOCOUNT ON
      
              --Start with a few simple error checks
              IF ( @TempTable = 'NULL' AND @PermanentTable = 'NULL' )
                  BEGIN
                      RAISERROR ( 'ERROR: Please select a TempTable or Permanent Table.',16,1 ) 
                  END
      
              IF ( @TempTable <> 'NULL' AND @PermanentTable <> 'NULL' )
                  BEGIN
                      RAISERROR ( 'ERROR: Only one table can be selected at a time. Please adjust your table selection.',16,1 ) 
                  END
      
              IF ( @TotalColumns IS NULL )
                  BEGIN
                      RAISERROR ( 'ERROR: Please select a value for @TotalColumns.',16,1 ) 
                  END
      
          --Temp table to gather the names of the columns
          IF Object_id('tempdb..#TempName') IS NOT NULL DROP TABLE #TempName
          CREATE TABLE #TempName ( ID INT, Name VARCHAR (1000) )
      
              --Select the column order from a temp table
              IF @TempTable <> 'NULL'
                  BEGIN       
                      --Verify the temp table exists
                      IF NOT EXISTS ( SELECT  1 
                                      FROM    tempdb.sys.columns
                                      WHERE   object_id = object_id ('tempdb..' + @TempTable +'') )
                      BEGIN 
                          RAISERROR ( 'ERROR: Your TempTable does not exist - Please select a valid TempTable.',16,1 ) 
                                  RETURN 
                              END 
      
                      SET @SQL = 'INSERT INTO #TempName
                                  SELECT  column_id AS ID, Name 
                                  FROM    tempdb.sys.columns
                                  WHERE   object_id = object_id (''tempdb..' + @TempTable +''')
                                  ORDER BY    column_id'
                      EXEC (@SQL) 
                  END
      
              --From a permanent table
              IF @PermanentTable <> 'NULL'
                  BEGIN       
                      --Verify the temp table exists
                      IF NOT EXISTS ( SELECT  1
                                      FROM    syscolumns
                                      WHERE   id =  ( SELECT id 
                                                      FROM sysobjects 
                                                      WHERE Name = '' + @PermanentTable + '' ) ) 
                      BEGIN 
                          RAISERROR ( 'ERROR: Your Table does not exist - Please select a valid Table.',16,1 ) 
                                  RETURN 
                              END 
      
                      SET @SQL = 'INSERT INTO #TempName
                                  SELECT   colorder AS ID, Name
                                  FROM     syscolumns
                                  WHERE id = ( SELECT id 
                                               FROM sysobjects 
                                               WHERE Name = ''' + @PermanentTable + ''' )
                                  ORDER BY colorder'
                      EXEC (@SQL)
                  END
      
              --Set the names of the columns
              IF @TotalColumns >= 1 BEGIN SET @Column1 = (SELECT Name FROM #TempName WHERE ID = 1) END
              IF @TotalColumns >= 2 BEGIN SET @Column2 = (SELECT Name FROM #TempName WHERE ID = 2) END
              IF @TotalColumns >= 3 BEGIN SET @Column3 = (SELECT Name FROM #TempName WHERE ID = 3) END
              IF @TotalColumns >= 4 BEGIN SET @Column4 = (SELECT Name FROM #TempName WHERE ID = 4) END
              IF @TotalColumns >= 5 BEGIN SET @Column5 = (SELECT Name FROM #TempName WHERE ID = 5) END
      
          --Create a select list of only the column names you want
          IF Object_id('tempdb..#FinalNames') IS NOT NULL DROP TABLE #FinalNames
          CREATE TABLE #FinalNames ( ID INT, Name VARCHAR (1000) )
      
                  INSERT  #FinalNames
                  SELECT  '1' AS ID, @Column1 AS Name UNION ALL
                  SELECT  '2' AS ID, @Column2 AS Name UNION ALL
                  SELECT  '3' AS ID, @Column3 AS Name UNION ALL
                  SELECT  '4' AS ID, @Column4 AS Name UNION ALL
                  SELECT  '5' AS ID, @Column5 AS Name
      
                  --Comma Delimite the names to insert into a select statement. Bracket the names in case there are spaces 
                  SELECT  @ColumnNamesAll = COALESCE(@ColumnNamesAll + '], [' ,'[') + Name
                  FROM    #FinalNames
                  WHERE   Name IS NOT NULL
                  ORDER BY ID
      
                  --Add an extra bracket at the end to complete the string
                  SELECT  @ColumnNamesAll = @ColumnNamesAll + ']'
      
              --Tell the user if they selected to many columns
              IF ( @TotalColumns > 5 AND EXISTS (SELECT 1 FROM #FinalNames WHERE Name IS NOT NULL) )
                  BEGIN
                      SELECT 'This script has been designed for up to 5 columns' AS ERROR
                      UNION ALL
                      SELECT 'Only the first 5 columns have been selected' AS ERROR
                  END
      
              IF Object_id('tempdb..#FinalNames') IS NOT NULL DROP TABLE ##OutputTable
      
              --Select results using only the Columns you wanted
              IF @TempTable <> 'NULL'
                  BEGIN
                      SET @SQL = 'SELECT  ' + @ColumnNamesAll + '
                                  INTO    ##OutputTable
                                  FROM     ' + @TempTable + ' 
                                  ORDER BY 1'
                      EXEC (@SQL)
                  END
      
              IF @PermanentTable <> 'NULL'
                  BEGIN
                      SET @SQL = 'SELECT  ' + @ColumnNamesAll + '
                                  INTO    ##OutputTable
                                  FROM     ' + @PermanentTable + ' 
                                  ORDER BY 1'
                      EXEC (@SQL) 
                  END
      
          SELECT  *
          FROM    ##OutputTable
      
          SET NOCOUNT OFF
      

      【讨论】:

        【解决方案5】:

        SQL 不理解列的顺序。您需要知道列名才能获取它们。

        您可以查看查询 information_schema 以获取列名。例如:

        SELECT column_name
          FROM INFORMATION_SCHEMA.COLUMNS
          WHERE table_name = 'tbl_name'
          ORDER BY ordinal_position
          LIMIT 2;
        

        【讨论】:

        • SQL Server Express 2008 在 LIMIT 2 位上出现错误 - 我可能应该提到我使用的是什么。
        【解决方案6】:

        你可以通过查询表的sysobject找出前两列然后动态生成你需要的SQL语句。

        【讨论】:

          【解决方案7】:

          如果您想要一个可以反复查询的永久对象,请为每个仅返回前 2 列的表创建一个视图。您可以命名列 Column1 和 Column2 或使用现有名称。

          如果您想在不进行任何预处理步骤的情况下从任何表返回前两列,请创建一个查询系统信息并执行从表中返回前两列的动态查询的存储过程。

          【讨论】:

            【解决方案8】:

            还是我必须先走很长一段路才能找到列名?我该怎么做?

            手动操作很容易。
            先运行这个

            select * from tbl where 1=0
            

            此语句适用于所有主要 DBMS,无需任何系统目录。 这给了你所有的列名,那么你需要做的就是输入前两个

            select colname1, colnum2 from tbl
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2012-05-13
              • 1970-01-01
              • 2018-03-21
              • 2020-06-03
              • 2023-03-12
              • 2017-05-21
              • 1970-01-01
              相关资源
              最近更新 更多