具有条件的列数据类型的SQL查询数据库

时间:2015-07-08 08:13:12

标签: sql sql-server sql-server-2008

例如,在SQL Server(10.0.5520.SQL Server 2008 SP3)中,我们有一个包含3列DateTime列的表。

我们的目标是只获取具有3列中的一列的数据> SpecificedDate但我们不希望逐个列出指定的列。

请查看以下示例:

TABLE A (ID INT, 
         Name VARCHAR, 
         CreateDate DATETIME, 
         ModifyDate DATETIME, 
         VoidDate DATETIME)

通常会是:

SELECT *
FROM A
WHERE CreateDate > 'X' OR ModifyDate > 'X' OR VoidDate > 'X'

应该转向

SELECT *
FROM A
WHERE (IF Column Is DateTime AND Column.Data > 'X')

我们可以这样查询吗?如果是,我们该怎么做?

3 个答案:

答案 0 :(得分:3)

您可以使用sys.columns获取datetime的给定表格的列。

select C.name
from sys.columns as C
where C.object_id = object_id('A') and
      C.system_type_id = type_id('datetime')

然后,您可以使用sp_executesql来构建和执行查询。

declare @SQL nvarchar(max)

set @SQL = '
select *
from dbo.A
where '+stuff((
              select 'or '+quotename(C.name) + ' > @Value '
              from sys.columns as C
              where C.object_id = object_id('A') and
                    C.system_type_id = type_id('datetime')
              for xml path(''), type
              ).value('text()[1]', 'nvarchar(max)'), 1, 3, '')


--print @SQL

exec sp_executesql @SQL, N'@Value datetime', '2015-07-01'
select *
from dbo.A
where [CreateDate] > @Value or [ModifyDate] > @Value or [VoidDate] > @Value 

答案 1 :(得分:1)

表A

ID  Name        CreateDate              ModifyDate              VoidDate
--- ----------- ----------------------- ----------------------- -----------------------
1   Name1       2015-01-01 00:00:00.000 2015-02-02 00:00:00.000 2015-03-03 00:00:00.000
2   Name2       2015-01-01 00:00:00.000 NULL                    NULL
3   Name3       NULL                    NULL                    2015-03-03 00:00:00.000
4   Name4       NULL                    NULL                    NULL

T-SQL代码

DECLARE @ColNames AS TABLE (RowNumber INT, ColumnName VARCHAR(MAX))
INSERT INTO @ColNames
    SELECT 
        RANK() OVER (ORDER BY c.COLUMN_NAME) AS RowNumber,
        c.COLUMN_NAME
    FROM 
        INFORMATION_SCHEMA.COLUMNS c
    WHERE
        TABLE_NAME = 'A' AND DATA_TYPE = 'datetime'
    ORDER BY RowNumber

DECLARE @SpecifiedDate DATETIME
SET @SpecifiedDate = '2015-01-01'

DECLARE @i INT = 1
DECLARE @sqlString NVARCHAR(MAX) = N'SELECT * FROM A WHERE '

DECLARE @count INT = (SELECT COUNT(*) FROM @ColNames)

WHILE @i <= @count
BEGIN
    DECLARE @colName VARCHAR(MAX) =
        (SELECT ColumnName FROM @ColNames WHERE RowNumber = @i)

    SET @sqlString = @sqlString + @colName + ' > ''' 
        + CONVERT(VARCHAR, @SpecifiedDate,104) + ''''

    SET @sqlString = @sqlString + 
        CASE WHEN @i < @count 
            THEN ' OR ' 
            ELSE '' 
        END

    SET @i = @i + 1;
END

EXEC sp_executesql @sqlString, N'@SpecifiedDate datetime', '2015-01-01'

输出

ID  Name   CreateDate              ModifyDate              VoidDate
--- ------ ----------------------- ----------------------- -----------------------
1   Name1  2015-01-01 00:00:00.000 2015-02-02 00:00:00.000 2015-03-03 00:00:00.000
3   Name3  NULL                    NULL                    2015-03-03 00:00:00.000

答案 2 :(得分:0)

Sql Server 2012+中,您可以使用TRY_CAST功能:

WHERE TRY_CAST(column1 AS DATETIME) > 'X' OR
      TRY_CAST(column2 AS DATETIME) > 'X' OR
      TRY_CAST(column3 AS DATETIME) > 'X'

Sql Server 2008中,您可以使用ISDATE功能:

WHERE (ISDATE(column1) = 1 AND CAST(column1 AS DATETIME) > 'X') OR
      (ISDATE(column2) = 1 AND CAST(column2 AS DATETIME) > 'X') OR
      (ISDATE(column3) = 1 AND CAST(column3 AS DATETIME) > 'X')