Mysql查询,更具体的是与Laravel雄辩

时间:2017-04-06 17:48:24

标签: php mysql laravel

我认为我在mysql查询知识方面达到了顶峰。我似乎无法生成,我怀疑是一个复杂的查询。这里有一些关于我的设置,然后是问题的背景知识。我有3张桌子。为简洁起见,我只列出相关的列。

customers
- id

customer_fields
- id
- name

customer_datas
- id
- customer_id
- customer_field_id
- value

此设置允许客户创建附加到客户的任意数量的字段。 customer_datas保存customers字段的值,并链接到数据项。例如:

customer (1 record)
- id: 1

customer_fields (2 records)
- id: 1
- name: firstname

- id: 2
- name: lastname

customer_datas (2 records)
- id: 1
- customer_id: 1
- customer_field_id: 1
- value: John

- id: 2
- customer_id: 1
- customer_field_id: 2
- value: Doe

这就是问题所在。我能够为每个客户甚至客户列表提取数据。我无法做的是按列排序数据,在这种情况下,它必须是某种伪列。

这是一个例子。我不能只运行一个ORDER BY名字,因为我的客户表上没有该列。它全部是动态的,因此firstname是客户端设置的字段,位于customer_fields表中。我希望能够通过客户端设置的任何customer_field来订购,但我担心我对mysql查询的了解有点受限。我也不确定Laravel雄辩是否有这样的能力。如果没有,我可以走原路。

我从来没有做过这么充满活力的事情,所以我愿意接受我的设置完全错误的可能性。任何帮助将不胜感激。甚至只是指着我正确的方向。

此外,如果已经在某处已经涵盖了这一点,请道歉。我觉得这是一个非常具体的案例,我无法找到有关它的任何信息。

3 个答案:

答案 0 :(得分:0)

我觉得你很困惑。有时Eloquent不是正确的查询方式,因为Eloquent将执行多个查询来获取数据。这可能会导致混淆如何正确构建您的查询。

最终,99%的时间用于更大,更复杂的查询,您将需要使用Fluent查询生成器。

以下是使用local Query Scope模型中使用Customer的自定义Fluent Query Builder的示例。

public function scopeOrderByCustomField($field, $direction) {
    Customer::join('customer_datas as ca', 'ca.customer_id', '=', 'customer.id')
        ->join('customer_fields as cf', 'cf.id', '=', 'ca.customer_field_id')
        ->where(cf.name, $field)
        ->orderBy('ca.value', $direction)
}

哪个应该最终为您提供Customer列表,该列表按照您传递的$field排序并转到您提供的$direction

在应用程序中,它看起来像这样:

$customers = Customer::orderByCustomField('first_name', 'ASC')->get();

注意,自己调用->get()非常重要,因为queryScope会返回Query Builder的实例,因此在调用{{1}之前不会获取任何结果}或->get()等。

答案 1 :(得分:0)

你使它变得过于复杂。所有这些数据都可以放在一个表中,即客户表。

->first()

然后,如果你喜欢地址表,可以打破数据。

customers
  - id
  - firstname
  - lastname

然后,您将根据customer_id等设置客户与他/她的地址之间的关系......您可以阅读更多关于laravel文档中关系的信息。 [laravel relations] [1]。 这对新桌子来说是有意义的。

  

没有理由让一个带有firstname的表只是指向   另一个带有实际“名字”的表。

更新

好的,然后再制作另一张表

addresses
 - id
 - customer_id
 - street
 - city
 - zip
 - etc.....

您可以从该表中动态添加和删除任意数量的字段。尽管如此,保持简单。

<强>更新

  customer_data
  - id
  - customer_id
  - field_name
  - field_data

答案 2 :(得分:0)

感谢所有发帖的人。我已经提出了正确的解决方案,部分原因在于您的所有输入:

我在客户模型上制作了一个范围

public function scopeOrderByCustomField($q, $field, $direction)
{

    $q->select('customers.*')
      ->join('customer_datas as ca', 'ca.customer_id', '=', 'customers.id')
      ->join('customer_fields as cf', 'cf.id', '=', 'ca.customer_field_id')
      ->where('cf.name', $field)
      ->groupBy('customers.id')
      ->orderBy('ca.value', $direction);

}

我必须添加select,因为customers表上的id被连接覆盖,并且需要添加groupBy,以便将客户分组到单个实体:)