代码之家  ›  专栏  ›  技术社区  ›  Zoltán Fekete

SQL中的速率计算

  •  1
  • Zoltán Fekete  · 技术社区  · 8 年前

    现在,我真的不知道该怎么解决这个问题。

    我的用户可以处理不同类型的任务。

    这些任务具有许多属性。我选择了 只有4个 的属性 简单

    如果我将任务分配给用户,我必须给出此分配的速率。这个比率将决定他完成任务后我必须为他支付多少费用。

    我有下表。这些id字段是 可为空 (除了user\u id),并且所有 外键

    |-#-|-user_id-|-type_id-|-task_id-|-source_id-|-target_id-|--rate--|
    | 1 |   12    |   NULL  |    1    |     1     |     2     | 0.0022 |
    | 2 |   12    |   NULL  |    2    |     1     |     2     | 0.0101 |
    | 3 |   12    |   NULL  |    1    |     2     |     1     | 0.0200 |
    | 4 |   12    |   NULL  |    2    |     2     |     1     | 0.1011 |
    | 5 |   12    |    1    |   NULL  |    NULL   |    NULL   | 0.0750 |
    | 6 |   12    |    2    |    1    |    NULL   |    NULL   | 0.0520 |
    | 7 |   12    |   NULL  |    1    |    NULL   |    NULL   | 0.9100 |
    

    当然也有其他用户的费率。

    现在有重量,从左到右的顺序( 来自列type\u id )。

    但是: 重要的是: 在左边 从第一列匹配开始,必须是全部 等于分配的任务值或NULL 价值观 向右 必须是 等于分配的任务值或NULL

    示例1

    user_id: 12
    type_id: 3
    task_id: 2
    source_id: 1
    target_id: 2
    

    #2-0.0101 应选择“速率”。

    示例2

    user_id: 12
    type_id: 1
    task_id: 2
    source_id: 3
    target_id: 4
    

    #5-0.0750 应选择“速率”。

    示例3

    user_id: 12
    type_id: 2
    task_id: 1
    source_id: 2
    target_id: 3
    

    #6-0.0520 应选择“速率”。

    到目前为止,我对此没有意见。但我无法解决以下问题:

    示例4

    user_id: 12
    type_id: 2
    task_id: 2
    source_id: 2
    target_id: 3
    

    应选择。

    示例5

    user_id: 12
    type_id: 3
    task_id: 1
    source_id: 2
    target_id: 3
    

    应选择。

    1 回复  |  直到 8 年前
        1
  •  1
  •   Gordon Linoff    8 年前

    我想你想要 order by fetch first row :

    select t.*
    from t
    where user_id = 12 and
          (type_id = 3 or type_id is null) and
          (task_id = 2 or task_id is null) and
          (source_id = 1 or source_id is null) and
          (target_id = 2 or target_id is null)
    order by ( (type_id is not null)::int +
               (task_id is not null)::int +
               (source_id is not null)::int +
               (target_id is not null)::int
             ) desc
    fetch first 1 row only;
    

    这将返回与您的条件匹配的行,但最少 NULL 值(即最具体的行)。

    编辑:

    如果需要按顺序匹配它们,则 where 子句如下所示:

    order by (type_id is not null)::int desc,
             (task_id is not null)::int desc,
             (source_id is not null)::int desc,
             (target_id is not null)::int desc