2013-06-25 25 views
0

我试图建立一个视图,我可以在我们的系统中使用,返回用户及其访问的标准化列表。TSQL:需要帮助优化这两部分记录

Table: Users 
UserID UserName  IsAdmin 
---------------------------------- 
1   John   0 
2   Jane   1 
3   Mary   0 

Table: Clients 
ClientID ParentClientID  ClientName 
---------------------------------- 
1   NULL    Pepsico 
2   1     Pizza Hut 
3   1     Taco Bell 
4   1     KFC 
5   NULL    McDonalds 

Table: UsersInClients 
UserID ClientID 
---------------------------------- 
1   2 
1   3 
2   1 
3   5 

我想要的输出:

UserID ClientID 
---------------------------------- 
1   2 --User 1 & 3 are not admins so list only includes IDs in UsersInClients table. 
1   3 
2   1 --If Users.IsAdmin = 1, it should return 
2   2 --all parent client and all child clients, 
2   3 --one row per client like this. 
2   4 
3   5 

我能想到这样做的唯一办法就是使用CTE和临时表,游标,等等,但我希望这可能是一个视图,以便我可以在我的查询中加入它。这可以做到吗?

谢谢你们

+0

仅供参考如果您仍然可以在视图定义中执行'CTE' ... – JNK

回答

0

您可以通过以下方式做到这一点,有两个查询的UNION。

(可能有办法做到这一切在一个单一的JOIN条件,但是这是更容易调试。)

SELECT UserId, ClientID 
FROM UsersInClients Uic INNER JOIN Users U ON Uic.UserId = U.UserID 
INNER JOIN Clients C ON (C.ClientID = Uic.ClientID OR C.ParentClientID = Uic.ClientID) 
WHERE U.IsAdmin = 1 

UNION ALL 

SELECT UserId, ClientID 
FROM UsersInClients Uic INNER JOIN Users U ON UIC.UserId = U.UserID 
INNER JOIN Clients C ON C.ClientID = Uic.ClientID 
WHERE U.IsAdmin = 0 
+0

谢谢JNK,已修复。 – Eterm

+0

另外,你假设他的客户亲子只有一个深度。尽管在我的例子中它只有一个深度,但它可能是5甚至10个深度。 – Losbear

+0

如果您需要多于1级的层次结构,那么我建议使用SQL 2008或更新版本的原生Hierarchy类型:http://msdn.microsoft.com/en-us/magazine/cc794278.aspx – Eterm

0

如果你有无限的层次,您的解决方案将是一个CTE。

WITH T AS 
(
    SELECT UC.UserId, UC.ClientId, U.IsAdmin 
    FROM UsersInClient UC 
    INNER JOIN Users U 
     ON UC.UserId = U.UserId 
    UNION ALL 
    SELECT T.UserId, C.ClientId, T.IsAdmin 
    FROM T 
    INNER JOIN Clients C 
     ON T.ClientId = C.ParentClientId AND T.IsAdmin = 1 
) 
SELECT * FROM T 

顺便说一句,这可能是一个看法。