SQL if(exists())查询重复

时间:2009-05-14 17:24:01

标签: sql

我需要编写一个从表中获取一组信息的查询,但如果没有该特定客户端的信息,则使用默认集。我想知道是否有办法避免if(exists())语句中的查询重复。

例如:

IF( EXISTS( SELECT * FROM UserTable WHERE Name = @UserName))
BEGIN
    SELECT * FROM UserTable WHERE Name = @UserName))
END
ELSE
BEGIN
    SELECT * FROM UserTable WHERE Name = 'Jon Skeet'))
END

前两个选择(存在和if的真实部分)完全相同。如果语句为true,我想避免两次运行相同的查询。我知道一旦满足第一个真实条件就存在停止,但这仍然是O(n)最坏的情况。

我知道的另一个选项是将信息放在临时表中,检查信息是否存在,如果没有返回默认信息。

两种方式都可以,但最好的方法是什么?还有其他方法吗?有没有办法在WHERE子句中执行此操作,因为这是唯一不同的东西?

编辑:修复了返回行而不仅仅是单个项目的示例。因此,将select转储到单个变量的答案将等于我假设的临时表。另外,不要愤怒Jon Skeet,拼错他的名字

6 个答案:

答案 0 :(得分:6)

你可以这样做:

SELECT TOP 1
     UserID
FROM
     UserTable
WHERE
     Name IN (@UserName, 'John Skeet')
ORDER BY
     CASE WHEN Name = 'John Skeet' THEN 2 ELSE 1 END

(或使用LIMIT或任何方法用于您的RDBMS)

或者你可以这样做:

DECLARE @UserID INT

SELECT
     @UserID = UserID
FROM
     UserTable
WHERE
     Name = @UserName

IF (@UserID IS NULL)
     SELECT
          @UserID = UserID
     FROM
          UserTable
     WHERE
          Name = 'John Skeet'

SELECT @UserID AS UserID

或者这个:

SELECT
     COALESCE(T2.UserID, T1.UserID)
FROM
     UserTable T1
LEFT OUTER JOIN UserTable T2 ON
     T2.Name = @UserName
WHERE
     T1.Name = 'John Skeet'

或者这个:

SELECT
     UserID
FROM
     UserTable
WHERE
     Name = @UserName

IF (@@ROWCOUNT = 0)  -- MS SQL Server specific, your RDBMS method will vary
     SELECT
          UserID
     FROM
          UserTable
     WHERE
          Name = 'John Skeet'

答案 1 :(得分:3)

怎么样:

DECLARE @UserID int;
SELECT @UserID = UserID FROM UserTable WHERE Name = @UserName

IF(@UserID IS NULL)
BEGIN
    SELECT @UserID=UserID FROM UserTable WHERE Name = 'Jon Skeet'))
END

SELECT @UserID

答案 2 :(得分:1)

如果变量返回,您可以选择变量检查变量null运行get default query

类似的东西:

Declare @uID int;

SELECT @uID = UserID FROM UserTable WHERE Name = @UserName

IF (@uID is null)
begin 
'Select default here'
End

select @uID

答案 3 :(得分:1)

如果您担心性能问题,我认为您可能不需要 - 大多数DBMS应该优化复制。如果您仍然关注性能,请同时运行它以查看您的DBMS是否存在任何问题。

如果您担心代码 - 重复代码部分的可维护性,可读性等,那么请记住上述答案。您可能会发现重复是最差的选择。令人遗憾的是SQL不具备可塑性。

答案 4 :(得分:0)

你没有说你正在使用什么DBMS,但显然不是Oracle(我知道的那个)。但是,我希望您的DBMS允许您执行类似此伪代码的操作:

SELECT UserID FROM UserTable WHERE Name = @UserName
IF <no data returned by that> 
BEGIN
    SELECT UserID FROM UserTable WHERE Name = 'John Skeet'
END

在Oracle中,这将是:

BEGIN
    SELECT UserID INTO v_UserID FROM UserTable WHERE Name = :UserName;
EXCEPTION
    WHEN NO_DATA_FOUND THEN
    SELECT UserID INTO v_UserID FROM UserTable WHERE Name = 'John Skeet';
END

答案 5 :(得分:0)

除非你要为你要返回的每个字段定义一组变量(并且它只有一条记录),我认为最有效的方法是进行两次调用。临时表可能会花费更多。