SQL更喜欢一条记录而不是另一条记录

时间:2018-11-13 17:05:31

标签: mysql sql

enter image description here

使用上述数据结构,我想基于model_id的分组,记录的重要性和最近的记录来取回记录。因此,对于这些数据,我想获取记录2、4、6、7和10。

  • 我想返回记录2,因为对于model_id 1,记录1和2具有相同的重要性,但是2是更新的。
  • 我想获取记录4,因为对于model_id 2,记录4的重要性高于记录3。
  • 我想取回记录6,因为对于model_id 3,记录5和6具有相同的重要性,但6是更新的。
  • 我想找回记录7,因为它是model_id 4的唯一记录,无论其重要性级别如何。
  • 我想找回记录10,因为它具有更高的重要性,并且它是model_id 5中最新的更高重要性记录。

分数字段对于查询并不是很重要,它只是在获取所需结果集时要使用的值。

我正在为此使用MySQL 5.6。

有人知道如何攻击吗?

编辑:向db-fiddle添加链接:https://www.db-fiddle.com/f/9ZEcpn7vfBebAxnEBtfAwe/0

这是我要返回的结果集:

2,  lower,  4.6, 1, 2018-10-02 12:00:00 
4,  higher, 6.3, 2, 2018-08-13 12:00:00 
6,  higher, 4.1, 3, 2018-08-23 12:00:00 
7,  higher, 7.1, 4, 2018-08-11 12:00:00 
10, higher, 4.7, 5, 2018-09-14 12:00:00

这是我所掌握的SQL,这要归功于有关使用DENSE_RANK()的线索。在本地的MySql Workbench中,它给我正确的结果,但在db-fiddle上却不太正确。

set @pk1 ='';
set @rn1 =1;
set @sal ='';
set @val =1;

SELECT  id,model_id,
        importance,
        denseRank
FROM
(
  SELECT  id,model_id,
          importance,
          @rn1 := if(@pk1=model_id, if(@sal=importance, @rn1, @rn1+@val),1) as denseRank,
          @val := if(@pk1=model_id, if(@sal=importance, @val+1, 1),1) as value,
          @pk1 := model_id,
          @sal := importance    
  FROM
  (
    SELECT  id,model_id,
            importance
    FROM    temp
    ORDER BY model_id,importance,created_at desc
) A
) B where denseRank = '1' group by model_id; 

2 个答案:

答案 0 :(得分:2)

不幸的是,您的MySQL版本没有row_number(),这是编写优先级查询的最常用方法。但是您仍然可以这样做:

select t.*
from t
where t.id = (select t2.id
              from t t2
              where t2.model_id = t.model_id
              order by find_in_set(t2.importance, 'lower,higher') desc,
                       created_at desc
              limit 1
             );

答案 1 :(得分:1)

根据定义的顺序,您可以使用用户定义的变量来确定model_id分区中的行号。

Field()函数允许我们对importance字段进行相应的排序。然后,我们可以简单地考虑所有行号等于1的行。

select dt2.*
from (
      select 
        @rn := case when @mid = dt.model_id then @rn + 1
                    else 1
               end AS row_no, 
        dt.id, 
        dt.importance, 
        dt.score, 
        @mid := dt.model_id as model_id, 
        dt.created_at 
      from 
      (
        select * 
        from temp
        order by model_id, 
                 field(importance, 'higher', 'lower'), 
                 created_at DESC 
      ) AS dt
      cross join (select @rn := 0, 
                         @mid := 0) AS user_init_vars 
    ) AS dt2 
Where dt2.row_no = 1
Order by dt2.model_id;

结果

| row_no | id  | importance | score | model_id | created_at          |
| ------ | --- | ---------- | ----- | -------- | ------------------- |
| 1      | 2   | lower      | 4.6   | 1        | 2018-10-02 12:00:00 |
| 1      | 4   | higher     | 6.3   | 2        | 2018-08-13 12:00:00 |
| 1      | 6   | higher     | 4.1   | 3        | 2018-08-23 12:00:00 |
| 1      | 7   | higher     | 7.1   | 4        | 2018-08-11 12:00:00 |
| 1      | 10  | higher     | 4.7   | 5        | 2018-09-14 12:00:00 |

View on DB Fiddle