【问题标题】:SQL Query on multiple conditional columns多个条件列上的 SQL 查询
【发布时间】:2018-02-28 06:54:29
【问题描述】:

请原谅我似乎无法弄清楚我能做什么的标题。我有一个MainTable 有一些列在另一个表DefTable 中定义@

已简化,因为此列从 Col1 运行到 Col99

主表

RowId Col1 Col2 Col3 Col4
----- ---- ---- ---- ----
  1    Y   N    N    N
  2    N   Y    N    N
  3    N   N    N    Y

定义表

Key Description
--- -----------
 1  Logistics
 2  Warehouse
 3  Packaging
 4  MainLobby

条件是:
如果一列被标记为Y,我应该根据DefTable中的键显示Description

此外,我正在研究是否有两个或更多列被勾选Y。如果发生这种情况。我应该ConcatenateLogistics, MainLobby这样的结果

预期输出

RowId Description
----- -----------
  1   Logistics
  2   Warehouse
  3   MainLobby

多个勾选列的可能性

RowId Description
----- -----------
  1   Warehouse, MainLobby

我一直在修补这个answer,但我仍然卡住了。请帮帮我。

【问题讨论】:

    标签: sql sql-server sql-server-2012


    【解决方案1】:

    您将使用Apply 运算符(即CROSS APPLY

    SELECT a.RowId, d.Description 
    FROM MainTable  t
    CROSS APPLY (
           VALUES (t.RowId, 1, t.Col1), (t.RowId, 2, t.Col2),
                  (t.RowId, 3, t.Col3), (t.RowId, 4, t.Col4)
                  ....
    )a(RowId, Id, Cols)
    INNER JOIN DefTable d ON d.[Key] = a.Id
    WHERE a.Cols = 'Y'
    

    【讨论】:

    • 是的,当我仅限于 4 个项目时,这是可以接受的。但我有大约 99 列,可能超过 99。想要更有活力,如果我有超过 2 个字段标记为 Y
    • 在 RowId 上加入 MainTable 和 DefTable 似乎不太好。请检查。
    • @Hexxed... 如果您没有定期更改列,那么这种方法将很有用,否则您将研究更动态的方式。
    • @YogeshSharma 谢谢这个解决方案也很有帮助
    【解决方案2】:

    我想这就是你要找的东西。

    您的数据如下所示:

    主表

     SELECT *  INTO #MainTable FROM (
      VALUES(1,'Y','N','N','N'),
      (2,'N','Y','N','N'),
      (3,'N','N','N','Y')
      ) AS A(RowId ,Col1 ,Col2 ,Col3 ,Col4)
    

    定义表

     SELECT * INTO #DefTable FROM (
     VALUES(1,'Logistics'),
     (2,'Warehouse'),
     (3,'Packaging'),
     (4,'MainLobby')
     )AS A([Key],[Description]) 
    

    查询:

     SELECT M.RowId ,
     CASE WHEN (Col1='Y' OR Col2='Y' OR Col3='Y' OR Col4='Y' )THEN D.Description ELSE '' END AS [Description] 
     FROM #MainTable M
     INNER JOIN #DefTable D ON D.[Key]=M.RowId
    

    动态方法:

    DECLARE @QUERY NVARCHAR(MAX),@COLUMNSQUERY NVARCHAR(MAX)
    
    SET @COLUMNSQUERY=(SELECT 'CASE '+(SELECT  'WHEN '+COLUMN_NAME +'=''Y'' THEN [DESCRIPTION] ' 
        FROM [tempdb].INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME like '#MainTable%' 
        and COLUMN_NAME <>'RowId' for xml path('') ) + 'ELSE '''' END AS [DESCRIPTION]' )
    
    SET @QUERY=' SELECT M.RowId ,'+@COLUMNSQUERY + 'FROM #MainTable M
    INNER JOIN #DefTable D ON D.[Key]=M.RowId'
    
    EXEC (@QUERY)
    

    注意:我从 Temp db 中选择了 temp 表的列。请用您的主表所在的实际数据库替换它

    用这个 FROM [YourDatabaseName].INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME like 'Your Main table Name%'

    替换这个条件 FROM [tempdb].INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME like '#MainTable%'

    【讨论】:

    • 是的,当我仅限于 4 个项目时,这是可以接受的。但我得到了大约 99 列,可能超过 99。
    • 我也添加了Dynamic Method。现在,检查更新的答案
    • 现在您无需在代码中对所有 99 多列进行硬编码。您只需使用该动态代码即可。
    猜你喜欢
    • 2021-12-13
    • 1970-01-01
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 2013-12-05
    • 2014-08-04
    相关资源
    最近更新 更多