SQL 如果值存在则 return 否则 return 整个 table

SQL If Value Exists then return that otherwise return whole table

注意:这是我正在尝试做的过于简化的版本。

假设我有一个名为 USERS 的 table,他有 FIRSTNAME、LASTNAME。内容是:

JOHN   SMITH
DAVID  BECKHAM
ELON   MUSK

我想查询这个 table,这样如果一个值存在,它只是 return 那个值,否则它 return 是整个 table。示例:

SELECT *
FROM USERS
WHERE FIRSTNAME = 'JOHN'

这会return

JOHN   SMITH

但是如果查询是

SELECT *
FROM USERS
WHERE FIRSTNAME = 'JANE'

那么return就是

JOHN   SMITH
DAVID  BECKHAM
ELON   MUSK

这是在 SQL 服务器中完成的,但如果它不同,Oracle 也有潜力。

如果您的 RDBMS 支持 CTE

,这是一个可能在 Oracle 或 SQL-server 中运行的示例

我们可以尝试用UNION ALLNOT EXISTS来制作

Filter FIRSTNAME in CTE if the first result exists value 这意味着你过滤一个 FIRSTNAME 然后你只会得到记录(因为 NOT EXISTS 不会让第二个结果集有效)。

;WITH CTE AS (
  SELECT *
  FROM USERS
  WHERE FIRSTNAME = 'JANE'
)
SELECT FIRSTNAME,LASTNAME
FROM CTE 
UNION ALL
SELECT FIRSTNAME,LASTNAME
FROM USERS 
WHERE NOT EXISTS (
   SELECT 1
   FROM CTE
)

sqlfiddle

您可以这样做 - 也许 SQL 方言之间的句法略有不同。在子查询的分析函数的 order by 子句中找到 'John' 的出现 - 那是您应该拥有绑定变量的地方。

select first_name, last_name
from   (
         select first_name, last_name,
                dense_rank() over (order by case first_name
                                     when 'John' then 1 end) as rn
         from   users
       )
where  rn = 1
;

这是如何工作的:当名字是 John(或任何输入)时,case 表达式分配值 1,并且 null除此以外。因此,要么某些行被分配 1 而其他行被分配 null,或者所有行都被分配 nulldense_rank 分析函数会将 1 分配给具有 non-null 值的行,将 2 分配给分配了 null 的行,否则 它将分配 1到 all 行,如果 all 行在 case 表达式中分配 null。然后外层查询只选择dense rank为1的行;这些是所有“John”行(如果有的话),否则它会选择 all 行。

您想要 select 一个名字匹配的行,或者在 table 中没有匹配该名字的行。几乎逐字翻译成 SQL:

SELECT *
FROM users
WHERE firstname = 'JOHN'
OR NOT EXISTS (SELECT * FROM users WHERE firstname = 'JOHN');

另一种选择是使用 TOP (1) WITH TIES

的排序列
SELECT TOP (1) WITH TIES
  FIRSTNAME,
  LASTNAME
FROM (
    SELECT FIRSTNAME, LASTNAME, 1 AS Ordering
    FROM USERS
    WHERE FIRSTNAME = 'JANE'

    UNION ALL

    SELECT FIRSTNAME, LASTNAME, 2
    FROM USERS
) u
ORDER BY Ordering;