【问题标题】:Switching Raw greatest-n-per-group MySQL query to Laravel query builder将 Raw best-n-per-group MySQL 查询切换到 Laravel 查询生成器
【发布时间】:2013-09-05 12:26:30
【问题描述】:

我想将原始的 mysql 查询移动到 Laravel 4 的查询构建器中,或者最好是 Eloquent。


设置

  • 用于存储游戏折扣码的数据库。
  • 折扣密钥存储在密钥集中,其中每个密钥集与一个游戏相关联(一个游戏可以有多个密钥集)。
  • 以下查询旨在返回键集和相关数据的表,以便在管理页面上查看。
  • “迄今为止使用的密钥”由计划事件计算,并定期存储/更新在表keySetLogs 的日志条目中。 (它很聪明,只在计数发生变化时记录数据)
  • 我们希望显示“使用的密钥”的最新值,这是一个“每组最大的数”问题。

原始查询

SELECT
    `logs`.`id_keySet`,
    `games`.`name`,
    `kset`.`discount`,
    `kset`.`keys_total`,
    `logs`.`keys_used`
FROM `keySets` AS `kset`
INNER JOIN
(
    SELECT
        `ksl1`.*
    FROM `keySetLogs` AS `ksl1`
    LEFT OUTER JOIN `keySetLogs` AS `ksl2`
        ON (`ksl1`.`id_keySet` = `ksl2`.`id_keySet` AND `ksl1`.`set_at` < `ksl2`.`set_at`)
    WHERE `ksl2`.`id_keySet` IS NULL
    ORDER BY `id_keySet`
)
AS `logs`
    ON `logs`.`id_keySet` = `kset`.`id`
INNER JOIN `games`
    ON `games`.`id` = `kset`.`id_game`
ORDER BY `kset`.`id_game` ASC, `kset`.`discount` DESC

注意:嵌套查询从日志中获取最新的keys_used 值。此greatest-n-per-group 代码与in this question 讨论的一样使用。

示例输出:

+-----------+-------------+----------+------------+-----------+
| id_keySet | name        | discount | keys_total | keys_used |
+-----------+-------------+----------+------------+-----------+
|         5 | Test_Game_1 |   100.00 |         10 |         4 |
|         6 | Test_Game_1 |    50.00 |        100 |        20 |
|         3 | Test_Game_2 |   100.00 |         10 |         8 |
|         4 | Test_Game_2 |    50.00 |        100 |        14 |
|         1 | Test_Game_3 |   100.00 |         10 |         1 |
|         2 | Test_Game_3 |    50.00 |        100 |         5 |
...

问题

我有 KeySetKeySetLogGame 创建并设置了关系函数的 Eloquent 模型。

  1. 如何在查询生成器中编写嵌套查询?
  2. 是否可以完全使用 eloquent 编写查询(无需手动编写连接)?

【问题讨论】:

  • 是不能使用子查询的问题吗?
  • 我不知道,这就是我要问的:) 我不知道你是否可以使用这样的子查询。查看查询生成器文档,它似乎不支持-&gt;join(DB::RAW()) 之类的东西,所以这可能是不可能的,我最终不得不对其进行硬编码。但基本上我希望有更多 Laravel 专业知识的人可以提供一些关于他们如何解决这个问题的见解。

标签: mysql laravel laravel-4 greatest-n-per-group eloquent


【解决方案1】:

我不知道 Laravel 或 Eloquent,所以我可能不应该发表评论,但如果不影响性能,那么在我看来,这个查询可以重写如下:

 SELECT ksl1.id_keySet
      , g.name
      , k.discount
      , k.keys_total
      , ksl1.keys_used
   FROM keySetLogs ksl1
   LEFT 
   JOIN keySetLogs ksl2
     ON ksl1.id_keySet = ksl2.id_keySet
    AND ksl1.set_at < ksl2.set_at
   LEFT
   JOIN keysets k
     ON k.id = l.id_keySet
   LEFT
   JOIN games g
     ON g.id = k.id_game
  WHERE ksl2.id_keySet IS NULL
  ORDER 
     BY k.id_game ASC
      , k.discount DESC

【讨论】:

  • ON k.id - l.id_keySet 行似乎不太正确,不确定您的意思。不幸的是,性能对于这个项目的规模非常重要。
猜你喜欢
  • 1970-01-01
  • 2015-12-13
  • 2019-03-09
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 2017-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多