【问题标题】:Laravel - How to convert a derived table containing concatenation queries into Eloquent syntax?Laravel - 如何将包含连接查询的派生表转换为 Eloquent 语法?
【发布时间】:2017-06-13 22:55:24
【问题描述】:

如何将以下内容转换为 Eloquent 语法?我知道那里有一个派生表,所以不确定 Laravel 中的正确语法是什么?

    SELECT firstname
, CONCAT_WS
( ', '
, CASE WHEN years = 0 THEN NULL ELSE CONCAT(years,' years') END
, CASE WHEN months = 0 THEN NULL ELSE CONCAT(months, ' months') END
, CASE WHEN days = 0 THEN NULL ELSE CONCAT(days, ' days') END
) lengthOfService
FROM
( SELECT firstname
, FLOOR(DATEDIFF(CURDATE(),startdate)/365.2425) years
, FLOOR((DATEDIFF(CURDATE(),startdate)/365.2425 - FLOOR(DATEDIFF(CURDATE(),startdate)/365.2425))* 12) months
, CEILING((((DATEDIFF(CURDATE(),startdate)/365.2425 - FLOOR(DATEDIFF(CURDATE(),startdate)/365.2425))* 12)
- FLOOR((DATEDIFF(CURDATE(),startdate)/365.2425 - FLOOR(DATEDIFF(CURDATE(),startdate)/365.2425))* 12))* 30) days
FROM users
) x

【问题讨论】:

  • Eloquent 是一个 ORM,它将物理关系表转换为对象。我认为它不适用于派生表。但是,您可以在用户表中添加范围以过滤到该派生表。
  • @apokryfos 理论上我可以把它包装成DB::raw() 吗?
  • 是的,你可以,但这并不是真正使用 Eloquent,而是使用查询构建器。
  • 查看query scopes 以防万一(如果您有用户模型,您可以确定范围)
  • 你可以使用 hydraRaw。虽然没有记录:laravel.com/api/5.3/Illuminate/Database/Eloquent/…

标签: mysql sql laravel


【解决方案1】:

Laravel 确实提供了 hydrateRaw

先做一个模型类,我会用 App\Models\MyHydratedUser

$query = "SELECT firstname, CONCAT_WS ( ', '
, CASE WHEN years = 0 THEN NULL ELSE CONCAT(years,' years') END
, CASE WHEN months = 0 THEN NULL ELSE CONCAT(months, ' months') END
, CASE WHEN days = 0 THEN NULL ELSE CONCAT(days, ' days') END
) lengthOfService
FROM
( SELECT firstname
, FLOOR(DATEDIFF(CURDATE(),startdate)/365.2425) years
, FLOOR((DATEDIFF(CURDATE(),startdate)/365.2425 - 
FLOOR(DATEDIFF(CURDATE(),startdate)/365.2425))* 12) months
, CEILING((((DATEDIFF(CURDATE(),startdate)/365.2425 - 
FLOOR(DATEDIFF(CURDATE(),startdate)/365.2425))* 12)
- FLOOR((DATEDIFF(CURDATE(),startdate)/365.2425 - 
FLOOR(DATEDIFF(CURDATE(),startdate)/365.2425))* 12))* 30) days
FROM users
) x";

$users = App\Models\HydratedUser::hydrateRaw($query);

$users 变量将保存 HydratedUser 模型的集合

【讨论】:

  • 谢谢。这很好用。我希望这种方法记录在 Laravel 官方文档中。
【解决方案2】:

Eloquent 没有提供这样的具体方法。您将需要使用DB::raw("...")(但我猜这不是解决方案),或DB::select("SELECT ...");

【讨论】:

    【解决方案3】:

    没有 Eloquent 和 Query Builder

    创建子查询并将DB::tableDB::rawselectRaw() 方法一起使用。

    $subQuery = DB::table('users')
        ->selectRaw('firstname,
            FLOOR(DATEDIFF(CURDATE(),startdate)/365.2425) years,
            FLOOR((DATEDIFF(CURDATE(),startdate)/365.2425 -
            FLOOR(DATEDIFF(CURDATE(),startdate)/365.2425))* 12) months, 
            CEILING((((DATEDIFF(CURDATE(),startdate)/365.2425 - 
            FLOOR(DATEDIFF(CURDATE(),startdate)/365.2425))* 12) - 
            FLOOR((DATEDIFF(CURDATE(),startdate)/365.2425 - 
            FLOOR(DATEDIFF(CURDATE(),startdate)/365.2425))* 12))* 30) days');
    
    DB::table(DB::raw('('.$subQuery->toSql().') as tableName')
        ->selectRaw("firstname, CONCAT_WS(', ', 
            CASE WHEN years = 0 THEN NULL ELSE CONCAT(years,' years') END, 
            CASE WHEN months = 0 THEN NULL ELSE CONCAT(months, ' months') END, 
            CASE WHEN days = 0 THEN NULL ELSE CONCAT(days, ' days') END) lengthOfService")
    

    【讨论】:

      猜你喜欢
      • 2021-08-10
      • 1970-01-01
      • 2019-01-03
      • 2018-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多