英文:
SQL: CASE or IF based on parameter with 2 different SELECTS
问题
以下是您要翻译的内容:
在搜索或弄清楚这个问题时遇到了麻烦,但我想这应该很容易。
我有一个员工表
姓名 管理员
-------------------------
金姆 是
约翰 是
扎克 否
蒂姆 否
我有一个@parameter值,它提供了运行报告的用户名
基本上,我只想根据参数(用户)是管理员还是不是管理员返回2个不同的结果
IF @NAME IN (SELECT NAME FROM employee where ADMIN = '是') THEN
SELECT NAME FROM employee -- 返回表中的所有用户名
ELSE
SELECT NAME FROM employee where NAME = @NAME -- 只返回1个用户名
END
有人能指点我如何正确返回这个吗?提前感谢!
希望这有助于您理解您的查询代码。如果您有其他问题,请随时提出。
英文:
Having trouble searching or figuring this out, but imagine it should be pretty easy.
I have an employee table
NAME ADMIN
-------------------------
Jim Y
John Y
Zack N
Tim N
I have a @parameter value which provides me the name that is running the report
I basically just want to return 2 different results based on if the parameter (user) is an admin
IF @NAME IN (SELECT NAME FROM employee where ADMIN = 'Y') THEN
SELECT NAME FROM employee -- return all names in table
ELSE
SELECT NAME FROM employee where NAME = @NAME -- just return the 1 username
END
Can someone point my in the right direction on how to return this properly? thanks in advance!
答案1
得分: 2
你应该抵制任何将这两种情况合并成单个 SELECT
语句的诱惑,因为每种情况的最佳执行计划不同(索引查找单行 vs. 全表扫描)。
你可能最好采取这样的方法,在非管理员情况下,只需命中满足 Name = @Name
的行一次(而不是首先查找是否为管理员,然后再获取实际值)。
如果他们不是管理员,你已经有了需要分配给标量变量的内容。如果他们是管理员,那么你可以继续进行完整的 select
。
DECLARE @Admin CHAR(1),
@SomeOtherColumn VARCHAR(50);
SELECT @Admin = Admin,
@SomeOtherColumn = SomeOtherColumn
FROM employee
WHERE Name = @Name /*Needs to be unique key*/
IF @Admin = 'Y'
SELECT Name,
SomeOtherColumn
FROM employee
ELSE
SELECT @Name AS Name,
@SomeOtherColumn AS SomeOtherColumn
WHERE @Admin IS NOT NULL /*If select to assign variables found no row return zero rows*/
英文:
You should resist any temptation to combine the two cases into a single SELECT
statement as the best execution plans for each won't be the same (index seek of a single row vs full scan).
You are probably best off doing something like this so in the non admin case you only need to hit the row where Name = @Name
once (rather than first to find out they are not an admin and again to get the actual values).
If they are not an admin you already have what you need assigned to scalar variables. If they are an admin you then move onto the full select
.
DECLARE @Admin CHAR(1),
@SomeOtherColumn VARCHAR(50);
SELECT @Admin = Admin,
@SomeOtherColumn = SomeOtherColumn
FROM employee
WHERE Name = @Name /*Needs to be unique key*/
IF @Admin = 'Y'
SELECT Name,
SomeOtherColumn
FROM employee
ELSE
SELECT @Name AS Name,
@SomeOtherColumn AS SomeOtherColumn
WHERE @Admin IS NOT NULL /*If select to assign variables found no row return zero rows*/
答案2
得分: 1
以下是翻译好的部分:
这应该适用于您:
SELECT NAME FROM employee where ADMIN = 'Y'
IF(@@ROWCOUNT > 0)
SELECT NAME FROM employee -- 返回表中的所有姓名
ELSE
SELECT NAME FROM employee where NAME = @NAME -- 仅返回一个用户名
英文:
This should work for you:
SELECT NAME FROM employee where ADMIN = 'Y'
IF(@@ROWCOUNT > 0)
SELECT NAME FROM employee -- return all names in table
ELSE
SELECT NAME FROM employee where NAME = @NAME -- just return the 1 username
答案3
得分: 0
谢谢@MartinSmith指出这一点,我只需要在上面的代码中删除THEN和END:
IF @NAME IN (SELECT NAME FROM employee where ADMIN = 'Y')
SELECT NAME FROM employee -- 返回表中所有姓名
ELSE
SELECT NAME FROM employee where NAME = @NAME -- 只返回一个用户名
谢谢!
英文:
thanks you @MartinSmith for pointing this out, all I had to do was remove the THEN and END in my code above:
IF @NAME IN (SELECT NAME FROM employee where ADMIN = 'Y')
SELECT NAME FROM employee -- return all names in table
ELSE
SELECT NAME FROM employee where NAME = @NAME -- just return the 1 username
Thanks!
答案4
得分: 0
你有一个小的紧张点。
你想要一个"脆弱的代码",在其中有两个用于SELECT语句的路径,这些路径可能会不同步吗?
还是你想要保持脆弱性以最大化查询计划?
请参见下面的回答。如果你的表很小,我更喜欢"非脆弱的"代码。
请注意,下面的版本只有一个SELECT子句... 但是where子句有一个偏差。
创建表 #MyTableOne (Name VARCHAR(16), IsAdmin CHAR(1) NOT NULL)
将数据插入 #MyTableOne (Name, IsAdmin)
SELECT 'Jim','Y'
UNION ALL SELECT 'John','Y'
UNION ALL SELECT 'Zack','N'
UNION ALL SELECT 'Tim','N'
DECLARE @NameParameter VARCHAR(128)
/* 在这里尝试不同的值 */
SELECT @NameParameter = 'Jim'
SELECT @NameParameter = 'Tim'
SELECT @NameParameter = 'NotInTheTable'
DECLARE @MatchCount INT = 0
SELECT @MatchCount = COUNT(*) FROM #MyTableOne myAlias WHERE myAlias.Name = @NameParameter AND myAlias.IsAdmin = 'Y'
SELECT Name, IsAdmin FROM #MyTableOne myOuterAlias
WHERE
@MatchCount = 0 OR (myOuterAlias.Name = @NameParameter AND myOuterAlias.IsAdmin = 'Y')
删除表 #MyTableOne
当你的表/列很"小"的时候,我曾经看到过非常脆弱的代码... 就像下面这样
如果 @MagicValue = 1
BEGIN
从dbo.MyTable中选择A、B、C JOIN (一些连接排列方式 版本1) where ( 讨厌的where子句 #1 )
END
如果 @MagicValue = 2
BEGIN
从dbo.MyTable中选择A、B、C JOIN (一些连接排列方式 版本2) where ( 讨厌的where子句 #2 )
END
如果 @MagicValue = 3
BEGIN
从dbo.MyTable中选择A、B、C JOIN (一些连接排列方式 版本3) where ( 讨厌的where子句 #3 )
END
它可能会迅速失控... 在我看来。
英文:
You have a little tension point.
Do you want "fragile code" where you have 2 paths for SELECT statements that can get out of sync?
Or do you want to keep fragility to maximize the query plan?
See my answer below. If your table is small, I prefer "non fragile" code.
Note, the version below has only ONE SELECT clause... but with a deviation on the where clause.
CREATE TABLE #MyTableOne (Name VARCHAR(16), IsAdmin CHAR(1) NOT NULL)
INSERT INTO #MyTableOne (Name, IsAdmin)
-------------------------
SELECT 'Jim', 'Y'
UNION ALL SELECT 'John', 'Y'
UNION ALL SELECT 'Zack', 'N'
UNION ALL SELECT 'Tim', 'N'
DECLARE @NameParameter VARCHAR(128)
/* experiment here with the different values */
SELECT @NameParameter = 'Jim'
SELECT @NameParameter = 'Tim'
SELECT @NameParameter = 'NotInTheTable'
DECLARE @MatchCount INT = 0
SELECT @MatchCount = COUNT(*) FROM #MyTableOne myAlias WHERE myAlias.Name = @NameParameter AND myAlias.IsAdmin = 'Y'
SELECT Name, IsAdmin FROM #MyTableOne myOuterAlias
WHERE
@MatchCount = 0 OR (myOuterAlias.Name = @NameParameter AND myOuterAlias.IsAdmin = 'Y')
DROP TABLE #MyTableOne
While your table/columns is "small", i have seen horribly fragile code....like the below
IF @MagicValue = 1
BEGIN
SELECT A, B, C from dbo.MyTable JOIN (some permutation of joins here version 1) where ( nasty where clause #1 )
END
IF @MagicValue = 2
BEGIN
SELECT A, B, C from dbo.MyTable JOIN (some permutation of joins here version 2) where ( nasty where clause #2 )
END
IF @MagicValue = 3
BEGIN
SELECT A, B, C from dbo.MyTable JOIN (some permutation of joins here version 3) where ( nasty where clause #3 )
END
It can get so out of control....quickly, IMHO.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论