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 ALL
和NOT 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
)
您可以这样做 - 也许 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
,或者所有行都被分配 null
。 dense_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;
注意:这是我正在尝试做的过于简化的版本。
假设我有一个名为 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
我们可以尝试用UNION ALL
和NOT 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
)
您可以这样做 - 也许 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
,或者所有行都被分配 null
。 dense_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;