SQL: Selecting columns based on column value from another table

前端 未结 2 865
北恋
北恋 2021-01-03 00:13

I have the following tables:

UserPrivileges: 
+--------+------+------+------+
| UserID | Col1 | Col2 | Col3 |
+--------+------+------+------+
|      1 |    0         


        
2条回答
  •  余生分开走
    2021-01-03 00:46

    The answer depends upon your requirements for the result. Do you require a result with a consistent set of columns, regardless of user privs? If so, you could set the disallowed values to null (or some other special value) using a IF clause, e.g.,

    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 = '#'
    

    Of course, the "special value" could be a problem, since you need a value that would never appear in the data. If you needed to know that difference between a null because the real value is null vs. null because it is a prohibited column then you can't use null.

    Another approach would have you simple include the privilege indicator for each column appear in the result, and let your business logic use that to determine which values are visible to the user.

    A very different approach would have the result set to contain only the allowed columns. In this case you'll need to build your sql statement dynamically. I don't know if you are doing this in a stored procedure or in a host language, but the basic idea is something like this:

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

    "execute" meaning whatever you have available to execute a string as a sql command.


    more after clarification by OP:

    Ok, you need sql function that returns a string that looks like "colname1, colname2, ...". The following resembles what it would look like in sql server. syntax

    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
    

提交回复
热议问题