在SQL Server表中查找值并获取下一列

时间:2017-10-09 09:52:58

标签: sql sql-server

我在SQL Server中有一个表,我需要为所有行找到具有相同值的列(称为'b67'),但我现在不知道列名(因为列的名称更改)常常)。我需要找到这个列并向下一列询问值的另一部分(2列总是在一起)。

表的示例(想象相同,但有更多'coso'):

ID |  coso1   |   c45   |   coso2     |   b63  |  Coso3 | d28
---+----------+---------+-------------+--------+--------+----
1  |   b63    |  1      |   d28       |  5     |   c45  |  3
2  |   b63    |  4      |   d28       |  6     |   c45  |  5  
3  |   b63    |  67     |   d28       |  1     |   c45  |  2 
4  |   b63    |  34     |   d28       |  5     |   c45  |  6
5  |   b63    |  8      |   d28       |  6     |   c45  |  9

2 个答案:

答案 0 :(得分:0)

目前还不是很清楚你到底需要什么,但看看那个sql:

create table test_columns
(
coso1 char(3),
c45 int,
coso2 char(3),
b63 int
);

insert into test_columns values ('b63', 1, 'd28', 5)

DECLARE @column_id INT,
        @name varchar(200),
        @query varchar(max),
        @next_column varchar(200)
DECLARE @cursor CURSOR
SET @cursor = CURSOR FOR
select name, column_id from sys.columns where object_name(object_id) = 'test_columns' and name like 'coso%'
OPEN @cursor
FETCH NEXT
FROM @cursor INTO @name, @column_id
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @query = 'SELECT 1 FROM dbo.test_columns HAVING  COUNT(distinct ' + @name + ') = 1';
    EXEC (@query);
    IF (@@ROWCOUNT = 1) 
    BEGIN
        SELECT @next_column = name FROM sys.columns where object_name(object_id) = 'test_columns' and column_id = @column_id + 1;
    SET @query = 'SELECT ' + @next_column + ', ' + @name + '  FROM dbo.test_columns';

    EXEC (@query);

    END
FETCH NEXT
FROM @cursor INTO @name, @column_id
END
CLOSE @cursor
DEALLOCATE @cursor

答案 1 :(得分:0)

您可以构建动态SQL来测试每一列。 我使用DM_EXEC_DESCRIBE_FIRST_RESULT_SET来获取列名,但您也可以使用SELECT * FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'MYTABLE'

我存储列号,列名和sql查询以测试temp(变量)表中的列,然后循环甚至列来测试传递的值。

应该有效

CREATE PROCEDURE FIND_VAL (
    @ValuetoFind varchar(100)
)
AS
BEGIN

    DECLARE @TABLENAME VARCHAR(100) = 'MYTABLE'


    DECLARE @S TABLE (ID INT PRIMARY KEY, SQL_CMD VARCHAR(255), [NAME] VARCHAR(32))
    DECLARE @SQL_CMD NVARCHAR(255) = ''
    DECLARE @ID INT = 0
    DECLARE @C INT

    ;WITH
    C AS (
        SELECT * FROM SYS.DM_EXEC_DESCRIBE_FIRST_RESULT_SET('SELECT * FROM '+@TABLENAME,NULL,1) 
    ),
    S AS (
        SELECT COLUMN_ORDINAL, 'SET @CNT= CASE WHEN EXISTS(SELECT TOP 1 1 FROM '+ @TABLENAME + ' WHERE ISNULL(' + [NAME] + ', '''')<>'''+@VALUETOFIND+''') THEN 0 ELSE 1 END' Q, [NAME]
        FROM C  
    )
    INSERT INTO @S
    SELECT * FROM S

    --SELECT * FROM @S

    WHILE EXISTS(SELECT TOP 1 1 FROM @S WHERE (ID % 2)=0 ORDER BY ID) BEGIN

        SELECT TOP 1 @ID=ID, @SQL_CMD = SQL_CMD FROM @S WHERE (ID % 2)=0 ORDER BY ID

        EXEC SP_EXECUTESQL @SQL_CMD, N'@CNT INT OUTPUT', @CNT=@C OUTPUT

        IF @C = 1 BEGIN
            SELECT [NAME] FROM @S WHERE ID=@ID+1
            RETURN
        END

        DELETE FROM @S WHERE ID = @ID
    END
    SELECT NULL [NAME]
END

输出

NAME
c45