【问题标题】:Get rows with a mix of specific values or null if value does not exist获取具有特定值混合的行,如果值不存在,则获取 null
【发布时间】:2022-01-20 17:24:00
【问题描述】:

我有一张像这样的桌子。

id value text type eqPath enabled
1 0 Unknown NULL NULL True
2 1 Production Production NULL True
3 2 Idle Idle NULL True
4 3 Maintenance Maintenance NULL True
5 4 Changeover Changeover NULL True
6 5 Cleaning Cleaning NULL True
7 6 Engineering Other NULL True
8 7 Training Other NULL True
9 8 Pause Idle NULL True
10 1 Running Production 'Seattle/Sorting/Line 1' True
11 1 Running Production 'Seattle/Sorting/Line 2' True
12 5 Washing Cleaning 'Seattle/Sorting/Line 2' False
13 10 Locked Out Maintenance 'Seattle/Sorting/Line 2' False

当我使用此代码时,我会返回带有eqPathNULL 的所有行。

SELECT *
FROM modes
WHERE eqPath IS NULL
id value text type eqPath enabled
1 0 Unknown NULL NULL True
2 1 Production Production NULL True
3 2 Idle Idle NULL True
4 3 Maintenance Maintenance NULL True
5 4 Changeover Changeover NULL True
6 5 Cleaning Cleaning NULL True
7 6 Engineering Other NULL True
8 7 Training Other NULL True
9 8 Pause Idle NULL True

现在我需要一个返回同一个表的表,但如果用户请求一个特定的eqPath,那么它也会显示在列表中,但值列必须是唯一的,其中包含eqPath 的行用NULL 替换该行 eqPath.

id value text type eqPath enabled
1 0 Unknown NULL NULL True
11 1 Running Production 'Seattle/Sorting/Line 2' True
3 2 Idle Idle NULL True
4 3 Maintenance Maintenance NULL True
5 4 Changeover Changeover NULL True
12 5 Washing Cleaning 'Seattle/Sorting/Line 2' False
7 6 Engineering Other NULL True
8 7 Training Other NULL True
9 8 Pause Idle NULL True
13 10 Locked Out Maintenance 'Seattle/Sorting/Line 2' False

这是我正在尝试的代码,但我意识到它是错误的。

SELECT DISTINCT *
FROM modes
WHERE eqPath = ?
OR eqPath IS NULL
GROUP BY value

【问题讨论】:

  • 基本上听起来你想要类似(伪代码)where ( (eqPath=@paramname or eqPath is null) or (@paramName is null)) - 命名参数 @paramname 是用户提供的
  • @Nikki9696 我确实标记了它。这是sql-serverMSSQL。我认为这些是同一回事。至于您的代码,当我尝试这样做时,我得到了 id 1 和 id 10 的行,它们是冲突的,因为它们具有相同的值。
  • 请更详细地描述如何“替换”该行。您当前的示例选择了'Seattle/Sorting/Line 2' 作为价值1,但为什么不选择'Seattle/Sorting/Line 1'

标签: sql sql-server tsql


【解决方案1】:

您可以使用ROW_NUMBER 标记行并在过滤器中使用它以获得预期的结果。

一个 sql 查询类似于 -

select id, value, text, type, eqPath, enabled
from 
   (select * ,  
      row_number() over( partition by value order by eqPath desc) rn 
   from <your-table>
   where (eqPath is null or eqPath = ?) ) tbl 
where rn = 1 
order by value

查询中的row_number 会为每一行放置一个行号,并在值更改时重置,因此最终那些行号匹配为 1 的行将是我们需要获取的行。

here是个小提琴

【讨论】:

    【解决方案2】:

    我想我想出了一个解决方案:

    SELECT * 
    FROM modes
    WHERE eqPath IS NULL
    AND value NOT IN (
        SELECT value 
        FROM modes 
        WHERE eqPath = ?
    )
    UNION
    SELECT * 
    FROM modes
    WHERE eqPath = ?
    ORDER BY value
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-16
      • 2023-03-03
      • 2021-05-01
      • 2017-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多