【问题标题】:SQL: Selecting columns based on column value from another tableSQL:根据另一个表中的列值选择列
【发布时间】:2012-01-30 08:56:53
【问题描述】:

我有以下表格:

UserPrivileges: 
+--------+------+------+------+
| UserID | Col1 | Col2 | Col3 |
+--------+------+------+------+
|      1 |    0 |    1 |    1 |
|      2 |    0 |    0 |    1 |
|      3 |    1 |    0 |    0 |
|      4 |    1 |    1 |    0 |
+--------+------+------+------+

Data:
+--------+------+------+------+
| DataID | Col1 | Col2 | Col3 |
+--------+------+------+------+
|      1 | A    | B    | C    |
|      2 | D    | E    | F    |
|      3 | G    | H    | I    |
|      4 | J    | K    | L    |
+--------+------+------+------+

我的问题最简单的形式与Data 表没有任何关系,但无论如何我只是解释一下,以免我做错了。

如何根据值从 UserPrivileges 中选择列名?这样我就可以在另一个查询中使用结果来仅选择那些列。

类似的东西:

SELECT (COLUMNS_NAME_QUERY_FROM_UserPrivileges(UserID='#')) WHERE DataID = '#' FROM Data

或者我不介意管理特定列的用户权限的更好方法。

【问题讨论】:

    标签: mysql sql database


    【解决方案1】:

    答案取决于您对结果的要求。无论用户权限如何,您是否需要具有一组一致列的结果?如果是这样,您可以使用 IF 子句将不允许的值设置为 null(或其他一些特殊值),例如,

    SELECT IF (p.col1 = 0 THEN NULL ELSE d.col1) AS col1, 
           IF (p.col2 = 0 THEN NULL ELSE d.col2) AS col2,
           IF (p.col3 = 0 THEN NULL ELSE d.col3) AS col3
    FROM Data d, 
         UserPrivileges p
    WHERE p.userId = '#' 
      AND d.DataId = '#'
    

    当然,“特殊值”可能是个问题,因为您需要一个永远不会出现在数据中的值。如果您需要知道 null 之间的区别,因为实际值为 null 与 null 因为它是禁止列,那么您不能使用 null。

    另一种方法是让您简单地将每个列的权限指示符包含在结果中,并让您的业务逻辑使用它来确定哪些值对用户可见。

    一种非常不同的方法会使结果集仅包含允许的列。在这种情况下,您需要动态构建您的 sql 语句。我不知道您是在存储过程中还是在宿主语言中执行此操作,但基本思想是这样的:

    string sqlCmd = "SELECT " 
        + (SELECT (FIELDS_NAME_QUERY(UserID='#') 
           FROM USER_PRIVILEGES 
           WHERE userid='#') 
        + FROM data d 
    execute sqlCmd
    

    “执行”表示您可以将字符串作为 sql 命令执行的任何内容。


    OP 澄清后的更多内容:

    好的,您需要返回一个看起来像“colname1, colname2, ...”的字符串的 sql 函数。以下类似于它在 sql server 中的样子。语法

    create function   
    FIELDS_NAME_QUERY (@userid int)  
    begin  
    select col1, col2, col3... INTO @col1priv, @col2priv, @col3priv FROM userPrivileges WHERE UserId = @UserId  
    declare @result varhcar(60)  
    set @result = ''  
    if (@col1priv = 1) @result = 'col1'  
    if (@col2priv = 1) @result = @result + ' ,col2'  
    if (@col3priv = 1) @result = @result + ' ,col3'  
    return @result  
    end
    

    【讨论】:

    • 第一个不是我要找的,第二个。我的问题是你会怎么写FIELDS_NAME_QUERY()
    • 作为存储过程/函数,还是使用某种编程语言?
    • 在 SQL 中,作为 S.P 或 Func。
    • 好的,你需要返回一个看起来像“colname1, colname2, ...”的字符串的sql函数
    【解决方案2】:

    没试过,不过应该可以的

    SELECT (SHOW COLUMNS FROM table WHERE expr) FROM data WHERE DataID = '#'
    

    查看此帖子了解详情 - How can I get column names from a table in Oracle?

    让我们知道你是如何解决这个问题的...

    【讨论】:

    • 这应该可以解决您的问题 - get column names from table having a particular value
    • 有没有人试过这个,至少在概念上?我不使用 mysql,但如果它有效,我会感到非常惊讶。这意味着show columns的结果是多态的,我认为mysql没有那种OO行为。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-16
    • 1970-01-01
    • 2022-09-29
    • 1970-01-01
    • 1970-01-01
    • 2013-12-29
    相关资源
    最近更新 更多