【问题标题】:SQL - Match value if exists; else match NULLSQL - 如果存在则匹配值;否则匹配 NULL
【发布时间】:2021-02-12 01:28:53
【问题描述】:

我有一个 SQL 表:

country state county city
'us' 'ny' 'steuben' NULL
'us' 'ny' 'steuben' 'city a'
'us' 'ny' 'steuben' 'city b'
'us' 'ny' NULL NULL
'us' NULL NULL NULL
NULL NULL NULL NULL

目标是进行某种查询,其中始终提供“国家、州、县和城市”,但表中可能不存在所提供的内容。如果未找到提供的属性,我想从列中获取相关的“NULL”值。

例子: 用户提供“us, ny, steuben, city b” --> 第 3 行

例子: 用户提供“us, ny, steuben, city c” --> 第 1 行,因为 'city c' 未知

例子: 用户提供“us, ny, hamilton, city a” --> 第 4 行,因为 'hamilton' 未知

最初的想法是:

SELECT * 
FROM [location] 
WHERE 
   (country = @country OR country IS NULL) AND
   ([state] = @state OR [state] IS NULL) AND
   (county = @county OR county IS NULL) AND
   (city = @city OR city IS NULL)

但是,这将不加选择地返回 NULL 行。我真正在寻找的是某种逻辑,例如:

SELECT * 
FROM [location] 
WHERE 
   (country = @country IF EXISTS OR country IS NULL) AND
   ([state] = @state IF EXISTS OR [state] IS NULL) AND
   (county = @county IF EXISTS OR county IS NULL) AND
   (city = @city IF EXISTS OR city IS NULL)

有人有潜在的解决方案吗?

注意:如果答案因数据库而异,我对 MS-SQL 感兴趣。

【问题讨论】:

  • 您的数据库是非规范化的。你有什么不能规范你的设计的原因吗?这样查询将更容易编写,因为您可以将用户的数据指定为一系列JOIN 约束。
  • 不,我想没有。它只是偶然“非规范化”(我对 SQL 很陌生)。我不确定你所说的标准化是什么意思。有没有你可以指点我的资源来证明你的意思?

标签: sql sql-server


【解决方案1】:

你可以使用过滤和order by:

select top (1) t.*
from t
where (t.country = @country or t.country is null) and
      (t.state = @state or t.state is null) and
      (t.county = @county or t.county is null) and
      (t.city = @city or t.city is city)
order by ( (case when t.country = @country then 1 else 0 end) +
           (case when t.state = @state then 1 else 0 end) +
           (case when t.county = @county then 1 else 0 end) +
           (case when t.city = @city then 1 else 0 end)
         ) desc;

关键是按照完全匹配的数量降序排列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-22
    • 2015-07-06
    • 1970-01-01
    相关资源
    最近更新 更多