Laravel按查询分组

时间:2018-10-15 08:54:04

标签: mysql laravel query-builder

我在Laravel中得到了这个查询:

function set_sub_categories(data, cat_id) {
  var closest_form_group = $(document).find('select.subcategory').closest('.form-group');
  if (data.subcategories.length) {
    $('.category-spinner').remove();
    $(closest_form_group).find('label span').remove();
    var section = '<div class="controls adpost-category" style="width:23%;position: relative;float: left; margin-right:10px; margin-bottom: 10px;">';
    section += '<div class="select-box subcategory select-box-error">';
    var options = "<option value='0'>Select a category...</option>";
    var closest_form_group = $('select.subcategory').closest('.form-group');

    $.each(data.subcategories, function(i, row) {
      options += "<option value='" + row.pk_i_id + "'>" + row.s_name + "</option>";
    });

    section += '<select class="subcategory ' + cat_id + '_subcategory subcategory_dropdown dynamic valid" style="opacity: 0;" aria-invalid="false" name="catId" id="catId" >';
    section += options;
    section += '</select>';
    section += '<a href="#" class="select-box-trigger">\n\
            <span class="select-box-label value ellipsis-ddl">\n\
                Select a category...\n\
            </span>\n\
            <span class="select-box-icon">0</span>\n\
            </a>';
    section += '</div>';
    section += '</div>';
    $(closest_form_group).append(section);

    $(".main-category")
    $(".subcategory").each(function() {
      $(this).addClass("select-box-error");
    });
    $(".category-label").addClass("text-red");
    $("#error-span").removeClass("hidden");
  }
}

计算端口是否具有某些设施。我现在遇到的问题是return $this->hasMany(Facility::class) ->select("id", "port_id", "facility", DB::raw("(SELECT count('*') FROM port_facilities WHERE has_it = 1) as has_it_true"), DB::raw("(SELECT count('*') FROM port_facilities WHERE has_it = 0) as has_it_false")) ->groupBy('facility'); 无法正常工作。它按设施而不是groupBy进行计数。知道我该如何解决吗?

2 个答案:

答案 0 :(得分:2)

您需要在此处使用条件聚合:

return $this->hasMany(Facility::class)
    ->select("facility",
        DB::raw("COUNT(CASE WHEN has_it = 1 THEN 1 END) AS has_it_true"),
        DB::raw("COUNT(CASE WHEN has_it = 0 THEN 1 END) AS has_it_false"))
    ->groupBy('facility');

这将对应于以下原始MySQL查询:

SELECT
    facility,
    COUNT(CASE WHEN has_it = 1 THEN 1 END) AS has_it_true,
    COUNT(CASE WHEN has_it = 0 THEN 1 END) AS has_it_false
FROM port_facilities
GROUP BY
    facility;

请注意,我没有在id子句中包含port_idSELECT,因为MySQL可能不接受这些列。通常,在进行GROUP BY facility时,我们只能选择facilityfacility以外的其他列的集合。

答案 1 :(得分:0)

您要在此处混合两个Laravel组件。 1是Eloquent的Relationship定义,另一个是QueryBuilder。

从查询开始,您的“适应”查询应介于以下几行中:

Facility::select("id", "port_id", "facility",
                DB::raw("(SELECT count('*') FROM port_facilities
                                    WHERE has_it = 1) as has_it_true"),
                DB::raw("(SELECT count('*') FROM port_facilities
                                    WHERE has_it = 0) as has_it_false"))
            ->groupBy('facility')->get();

如果您希望建立关系,则在模型中要指定关系,您应该执行文档中列出的操作:

https://laravel.com/docs/5.7/eloquent-relationships#defining-relationships

建议:除非确实需要count('*')(除非您可以统计单个列或一对,以提高一些性能),否则不要将QueryBuilder与Eloquent混合使用,除非您确实需要和< / p>