使用Laravel的Eloquent(或Fluent)将一行数据复制到另一行

时间:2014-07-30 18:09:46

标签: laravel laravel-4 eloquent fluent

这是交易。我用两个或多或少的表来设置我的数据库如下(实际上,我的表格要复杂得多,但这是要点):

TABLE` elements`

  • ID
  • 数据

表`element_drafts`

  • ID
  • element_id
  • 数据

正如您可能从名称中猜到的那样,第二个表包含第一个表中的行草稿行。 (不要担心建议更好的方法来做草稿=)我的表比显示的更复杂,并且有一个草稿表是最好的解决方案atm)。

我在两个表之间建立了一个关系,这样我就可以做到这样的事情:

// Get all of the elements along with their draft rows
$elements_with_drafts = Element::with('drafts')->all();

我也可以通过这样做只选择有草稿行的元素:

$elements_with_drafts = Element::with('drafts')
    ->whereIn('id', function($query)
    {
        $query->select('element_id')->from('element_drafts');
    })
    ->get();

但我想做的一件事我无法弄清楚:将草稿值复制到其父元素。

最后,我的目标是通过单个查询将所有element_drafts ['data']值复制到其父元素['data']字段。

我不完全确定这是可能的。是吗?

我的猜测是,它可能会这样做:

$elements_with_drafts = Element::with('drafts')
    ->whereIn('id', function($query)
    {
        $query->select('element_id')->from('element_drafts');
    })
    ->update(array("data" => function($query)
    {
        // Somehow select the draft value?
    });

我觉得我很亲密,但我不太确定如何做我想做的事。有什么想法吗?

注意:显然这可以通过foreach循环相对容易地完成,但我希望解决方案只是一个查询。

2 个答案:

答案 0 :(得分:7)

和@ Ben's一样,只有他犯了一些错误:

DB::statement('UPDATE elements e
    JOIN element_drafts d ON e.id = d.element_id
    SET e.data = d.data');

实际上你也可以使用Query Builder

DB::table('elements as e')
    ->join('element_drafts as d', 'd.element_id', '=', 'e.id')
    ->update(['e.data' => DB::raw('d.data')]);

两者都会起作用。

请注意,它会将e.data设置为加入的第一行d.data(如果您的草稿多于每个元素一个草稿)。

答案 1 :(得分:2)

DB::statement('UPDATE elements e
               JOIN drafts d
               SET e.data = d.data WHERE e.id = d.element_id');

编辑:检查deczo对Query Builder解决方案的回答。