2016-09-23 79 views
1

我有一个用户表。其中包括以下4列:如何连接表与自己,第二个“ON”条件,如果一行为空

------ UserID ------- | ---- Username ----- | --- CreatedBy --- | ParentUserID

(PK,bigint,not null)| (char(20),not null)| (varchar(50),null)| (BIGINT,NULL)


两个ParentUserID和CreatedBy点在 “拥有者帐户”,分别由用户ID或用户名。两者都是独特的。

CreatedBy实际上从来没有实际上是null,但UserID已编入索引,因此ParentUserID是首选 - 这也是我们正朝着这一目标迈进的一步。

显然我不是精通SQL,但是这是我的想法是:

SELECT Users.* 
    FROM tblUsers AS Owners 
    LEFT JOIN tblUsers AS Users 
     ON 
     ISNULL(Users.ParentUserID = Owners.UserID, 
      Users.CreatedBy = Owners.Username) 
    WHERE Owners.UserID = 14; 

这是据我已经得到了:

SELECT ISNULL(POwners.UserID, COwners.UserID) AS OwnerID, Users.* 
    FROM tblUsers AS Users 
    RIGHT JOIN tblUsers AS POwners ON Users.ParentUserID = POwners.UserID 
    RIGHT JOIN tblUsers AS COwners ON Users.CreatedBy = COwners.Username 
WHERE OwnerID = 14; 

虽然显然这并未”工作。在第二个说明中,我还需要将其转换为LINQ,但对于此问题,它仅与目前相关的查询有可能进行转换,这是我期望的绝大多数查询。

回答

0

这似乎是没有的伎俩,我查询:

SELECT Users.* 
    FROM tblUsers AS Owners 
    LEFT JOIN tblUsers AS Users 
     ON Users.ParentUserID = Owners.ParentUserID 
     OR Users.CreatedBy = Owners.Username 
    WHERE Owners.UserID = 14; 

感谢Marc B的帮助。


至于LINQ,它变成了only equijoins are supported,所以我做了一个交叉连接这样的:

from u in dbContext.tblUsers 
from o in dbContext.tblUsers 
where (u.ParentUserID == o.UserID || u.CreatedBy == o.Username) 
    && o.UserID == 14 
select u; 

这变成下面的查询:

SELECT Users.* 
    FROM tblUsers AS Users 
     CROSS JOIN tblUsers AS Owners 
    WHERE(Users.ParentUserID = Owners.UserID OR Users.CreatedBy = Owners.Username) 
     AND(Owners.UserID = 14) 
0

join条件只是布尔测试,所以你需要编写一个适当的布尔条件,例如, (P or Q) AND R。你不能,把它们连,所以......

... ON ISNULL((Users.ParentUserID = Owners.UserID) AND (Users.CreatedBy = Owners.Username)) 

或任何你需要的逻辑是。使其成为有效的布尔表达式是关键部分。

+0

我用的是[ 'ISNULL(a,b)'](https://msdn.microsoft.com/en-us/library/ms184325.aspx),因为我的印象是它使用第二个值,如果第一个值是'null'。类似于C#中的空合并运算符:'var user = firstUser ?? secondUser;'顺便说一句,它应该读取像'Users.ParentUserID = Owners.UserID或用户.CreatedBy = Owners.Username' –

+1

你不能只是有'(a = b)或(C = d)'? –

+0

是的,这是一个有效的表达式 - 并返回正确的行数。但我不知道这是否正确,也不知道如何验证。如果第一个条件为真,它是否返回行,而不检查第二个条件? –

相关问题