我有 3 个代表对象的相关表:客户、用户和潜在客户。用户具有“用户”或“管理员”类型,可以创建潜在客户并为客户提供服务。在模式术语中,多对一关系中的Users.Client引用和多对一关系中的引用。示例架构:Clients.Id``Leads.CreatedBy``Users.Username
Users.Client
Clients.Id``Leads.CreatedBy``Users.Username
CREATE TABLE Clients ( Id INT IDENTITY PRIMARY KEY, Name VARCHAR(32) NOT NULL ); CREATE TABLE Users ( Id INT, Username VARCHAR(32) NOT NULL, Type VARCHAR(8) NOT NULL CHECK (Type IN ('Admin', 'User')), Client INT NOT NULL, PRIMARY KEY (Username), UNIQUE (id), FOREIGN KEY (Client) REFERENCES Clients (Id) ); CREATE TABLE Leads ( Id INT IDENTITY PRIMARY KEY, Name VARCHAR(64), Company VARCHAR(64), Profession VARCHAR(64), CreatedBy VARCHAR(32) NOT NULL, FOREIGN KEY (CreatedBy) REFERENCES Users (Username) );
我正在编写一个查询来向用户展示他们的潜在客户。“用户”类型的用户应该只能查看他们创建的潜在客户。“管理员”类型的用户应该能够看到他们客户的所有潜在客户(但不能看到其他客户)。什么查询会Leads根据这些限制从表中获取行?我检查了其他问答,但我不知道如何将它们应用于上述情况。
Leads
我尝试了以下方法:
SELECT * FROM Leads WHERE createdby IN ( CASE WHEN (SELECT type FROM users WHERE username='Sathar' )='Admin' THEN ( SELECT username FROM users WHERE client=( SELECT client FROM users WHERE username='Sathar' ) ) ELSE 'Sathar' END )
但是,它会产生错误:
子查询返回超过 1 个值。当子查询跟随 =、!=、<、<=、>、>= 或子查询用作表达式时,这是不允许的。
为了完善该示例,一些示例数据:
SET IDENTITY_INSERT Clients ON; INSERT INTO Clients (Id, Name) VALUES (1, 'IDM'), (2, 'FooCo') ; SET IDENTITY_INSERT Clients OFF; INSERT INTO Users (Id, Username, Type, Client) VALUES (1, 'Sathar', 'Admin', 1), (2, 'bafh', 'Admin', 1), (3, 'fred', 'User', 1), (4, 'bloggs', 'User', 1), (5, 'jadmin', 'Admin', 2), (6, 'juser', 'User', 2) ; INSERT INTO Leads (Name, Company, Profession, CreatedBy) VALUES ('A. Person', 'team lead', 'A Co', 'Sathar'), ('A. Parrot', 'team mascot', 'B Co', 'Sathar'), ('Alice Adams', 'analyst', 'C Co', 'juser'), ('"Bob" Dobbs', 'Drilling Equipment Salesman', 'D Co', 'juser'), ('Carol Kent', 'consultant', 'E Co', 'juser'), ('John Q. Employee', 'employee', 'F Co', 'fred'), ('Jane Q. Employee', 'employee', 'G Co', 'fred'), ('Bob Howard', 'Detached Special Secretary', 'Capital Laundry Services', 'jadmin') ;
以上所有内容都可以作为一个活生生的例子。
如果没有CASE表达式,查询不会产生错误,但不会遵循所有限制(为类型的用户返回客户端的所有潜在客户User):
CASE
User
SELECT * FROM Leads WHERE createdby IN ( SELECT username FROM users WHERE client=( SELECT client FROM users WHERE username='fred' ) )
这可以从另一个实例中显示的结果中看出。
这应该作为一个if elsenot as a来完成case,你可以这样做:
if else
case
if (SELECT type FROM users WHERE username='[the username]') = 'Admin' begin --The records you allow for admin to see for example (SELECT * FROM Leads where createdby in ( select username from users where client=(select client from users where username='Sathar') )) end else begin --The records you allow for non admin to see for example (SELECT * FROM Leads WHERE createdby = 'Sathar') end
或者真的’admin’应该用joins来完成,但同样的想法。
join
应该这样做的原因if else是因为case它是一个表达式而不是一个语句(就像在其他语言中一样switch case),while是一个条件语句,当你为每种类型的用户if else设置单独的 s 时,它会更好的设计,它会帮助你select不要制造错误。
switch case
select