mysql SQL使用join选择最近的值

nkhmeac6  于 2024-01-05  发布在  Mysql
关注(0)|答案(2)|浏览(154)

有两张table:
参考:

  1. id | score | value | type_id
  2. 1 | 0 | 10 | 1
  3. 2 | 1 | 20 | 1
  4. 3 | 2 | 30 | 1
  5. .. | .. | .. | ..

字符串
结果:

  1. id | score | type_id
  2. 1 | 2 | 1
  3. 2 | 7 | 2
  4. 3 | 0 | 3


我想根据result表中的score,从refernce表中为每个type_id获取value
查询:

  1. SELECT ref.score, ref.value, ref.type_id
  2. FROM `refernce` ref
  3. JOIN `result` res
  4. ON ref.type_id = res.type_id
  5. WHERE res.score >= ref.score
  6. GROUP BY ref.type_id
  7. ORDER BY ref.id DESC;


在这种情况下,输出应该是:

  1. score | value | type_id
  2. 0 | 8 | 3
  3. 3 | 25 | 2
  4. 2 | 30 | 1


但这是实际输出:

  1. score | value | type_id
  2. 0 | 8 | 3
  3. 0 | 5 | 2
  4. 0 | 10 | 1


因此,如果result表中的score存在于refernce中,则此分数的value,并且如果result表中的score大于refernce表中的value,则应返回大于scorevalue,即3。
这是一把小提琴:http://sqlfiddle.com/#!9/ecf 1 e3/1

dbf7pr2w

dbf7pr2w1#

使用MAX:)获取最大值...然后基于这两个值再次加入...

  1. SELECT ref.score
  2. , subsel.max_val
  3. , subsel.type_id
  4. FROM (
  5. SELECT res.score, max(ref.value) as max_val, ref.type_id
  6. FROM `refernce` ref
  7. JOIN `result` res
  8. ON ref.type_id = res.type_id
  9. WHERE res.score >= ref.score
  10. GROUP BY res.score, ref.type_id
  11. ) subsel
  12. JOIN `refernce` ref
  13. ON ref.type_id = subsel.type_id
  14. AND ref.value = subsel.max_val
  15. WHERE 1=1
  16. ORDER BY 3 desc;

字符串
如果你使用的是一些更复杂的数据库(Postgre,Oracle,...)
您可以使用窗口函数来分区和排序行..然后只在随后的筛选中选择您需要的行
示例(未测试)

  1. SELECT score_ref
  2. , value
  3. , type_id
  4. FROM (
  5. SELECT res.score as score_res
  6. , ref.score as score_ref
  7. , ref.value
  8. , ref.type_id
  9. , row_number() over (partition by ref.type_id order by ref.value desc) as row_order
  10. FROM `refernce` ref
  11. JOIN `result` res
  12. ON ref.type_id = res.type_id
  13. WHERE res.score >= ref.score
  14. GROUP BY ref.type_id
  15. )
  16. WHERE row_number = 1

展开查看全部
2o7dmzc5

2o7dmzc52#

只使用一个子查询的解决方案,来自链接referenceresult数据表,其中scorevalue数据行会转换成固定长度的十六进制字串表示,然后加以组合,并套用max汇总函数,再将十六进制字串转换回整数。

  1. select
  2. conv(substr(binstr, 1, 3), 16, 10) as score,
  3. conv(substr(binstr, -5), 16, 10) as `value`,
  4. type_id
  5. from (
  6. select
  7. max(concat(
  8. lpad(conv(ref.score, 10, 16), 3, '0'),
  9. lpad(conv(ref.`value`, 10, 16), 5, '0')
  10. )) as binstr,
  11. ref.type_id
  12. from reference as ref
  13. join result as res
  14. on ref.type_id = res.type_id and
  15. ref.score <= res.score
  16. group by ref.type_id
  17. ) as t;

字符串
测试结果:

  1. +-------+-------+---------+
  2. | score | value | type_id |
  3. +-------+-------+---------+
  4. | 2 | 30 | 1 |
  5. | 3 | 25 | 2 |
  6. | 0 | 8 | 3 |
  7. +-------+-------+---------+


SQL小操作。

展开查看全部

相关问题