2011-12-30 92 views
6

tôi có các bảng sau:SQL: Chọn các cột dựa trên giá trị cột từ bảng khác

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 | 
+--------+------+------+------+ 

Câu hỏi của tôi ở dạng đơn giản nhất không có bất cứ điều gì để làm với bảng Data nhưng tôi chỉ giải thích nó anyways để tôi có thể làm điều đó một cách sai lầm.

Làm cách nào để chọn tên cột từ UserPrivileges dựa trên giá trị? Để tôi có thể sử dụng kết quả trong truy vấn khác để chỉ chọn những cột đó.

cái gì đó dọc những dòng này:

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

Hoặc Tôi không quan tâm một cách tốt hơn để quản lý quyền ưu đãi người dùng cho các cột cụ thể.

Trả lời

6

Câu trả lời tùy thuộc vào yêu cầu của bạn cho kết quả. Bạn có yêu cầu kết quả với một tập hợp các cột nhất quán, bất kể người dùng cá nhân không? Nếu vậy, bạn có thể thiết lập các giá trị không được phép null (hoặc một số giá trị đặc biệt khác) sử dụng một điều khoản NẾU, ví dụ:

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

Tất nhiên, "giá trị đặc biệt" có thể là một vấn đề, vì bạn cần một giá trị sẽ không bao giờ xuất hiện trong dữ liệu. Nếu bạn cần phải biết rằng sự khác biệt giữa một null vì giá trị thực là null so với null vì nó là một cột bị cấm thì bạn không thể sử dụng null.

Một cách tiếp cận khác sẽ giúp bạn đơn giản bao gồm chỉ báo đặc quyền cho từng cột xuất hiện trong kết quả và để logic nghiệp vụ của bạn sử dụng để xác định giá trị nào hiển thị cho người dùng.

Cách tiếp cận rất khác sẽ có kết quả được đặt để chỉ chứa các cột được phép. Trong trường hợp này, bạn sẽ cần phải tự động xây dựng câu lệnh sql của mình. Tôi không biết nếu bạn đang làm điều này trong một thủ tục lưu trữ hoặc bằng một ngôn ngữ sở tại, nhưng ý tưởng cơ bản là một cái gì đó như thế này:

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

"thực" có nghĩa là bất cứ điều gì bạn có sẵn để thực hiện một chuỗi như một lệnh sql.


hơn sau khi làm rõ bởi OP:

Ok, bạn cần chức năng sql trả về một chuỗi trông giống như "colname1, colname2, ...". Sau đây tương tự như những gì nó sẽ giống như trong máy chủ sql. cú pháp
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

+0

Người đầu tiên không phải là những gì tôi đang tìm kiếm, và thứ hai. câu hỏi của tôi là bạn sẽ viết 'FIELDS_NAME_QUERY()' như thế nào? –

+0

Là thủ tục/chức năng được lưu trữ, hoặc bằng một số ngôn ngữ lập trình? –

+0

Trong SQL, hoặc là S.P hoặc Func. –

0

đã không thử nó, nhưng một cái gì đó như thế này nên làm việc

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

Kiểm tra bài viết này để biết chi tiết - How can I get column names from a table in Oracle?

Cho chúng tôi biết cách bạn giải quyết này ...

+0

Điều này sẽ giải quyết vấn đề của bạn - [lấy tên cột từ bảng có giá trị cụ thể] (http://stackoverflow.com/questions/5631822/to-get-column-names-from-table-having-a-particular-value) –

+0

có ai đã thử điều này, ít nhất là trong khái niệm? Tôi không sử dụng mysql nhưng tôi sẽ rất ngạc nhiên nếu nó hoạt động. Nó có nghĩa là kết quả của cột hiển thị là đa hình, và tôi không nghĩ rằng mysql có loại hành vi OO đó. –

Các vấn đề liên quan