如何使用查询生成器Laravel构建具有联接查询和子查询的复杂查询

时间:2018-09-05 12:58:29

标签: php mysql laravel

晚安,我的编码员朋友,

正如该问题的标题所述,我有一个稍微复杂的mysql查询,我试图使用Laravel中的查询生成器将其记录下来,但是每次尝试写入时,我都会在到达子查询时停止。我将写下查询,也将让您知道查询的作用。

SELECT 
    brands.name_en as brand_name_en, 
    brands.name_ar as brand_name_ar, 
    brands.brand_url as brand_url, 
    brands.description_ar as description_ar, 
    brands.description_en as description_en, 
    categories.name_en as category_name_en,
    categories.name_ar as category_name_ar     
FROM 
    brands 
    INNER JOIN categories ON brands.category_id = categories.id     
WHERE 
    (brands.status = "1") 
    AND
    (
        brands.id IN (
            SELECT 
                distinct(items.brand_id) 
            FROM 
                items 
            WHERE 
                items.in_stock = "1" 
            GROUP BY 
                (items.brand_id)
        )
    )

查询说明:

我有三个表:

  • 品牌(id,名称,category_id)
  • 类别(id,名称,brand_id)
  • 物品(id,brand_id,入库库存,销售日期)

现在我要执行以下操作: 我想检索(品牌名称和类别名称)并根据上个月的最高销售额对其进行排序

这是表中包含数据的示例:

Brands Table 
------------
id     name           category_id
1      googleplay     1


Categories Table 
--------------------------
id     name           brand_id
1      cards          1


items Table
-----------
id     brand_id    in_stock       selling_date
1      1           0              null
1      1           1              2017-02-02 04:04:49

尝试了将近2天,但运气不佳,因为它到达子查询部分时确实很复杂。

真的希望从你们那里寻求帮助。并且让我知道你们是否需要更多解释,我在写问题时可能会忘记一些东西。

谢谢。

2 个答案:

答案 0 :(得分:1)

如果您稍微更改了sql,则可以使用内部联接来实现它:

SELECT brands.name, categories.name
FROM brands 
INNER JOIN categories ON brands.category_id = categories.id 
INNER JOIN items ON categories.id = items.brand_id
WHERE brands.status = 1 AND items.in_stock = 1

将其翻译为Laravel很简单:

\DB::table('brands')
    ->join('categories', 'brands.category_id', '=', 'categories.id')
    ->join('items', 'brands.id', '=', 'items.brand_id')
    ->select('brands.name as brand', 'categories.name as category')
    ->where('brands.status', 1)
    ->where('items.in_stock', 1)
    ->get();

答案 1 :(得分:1)

从概念上讲,我们如何从上个月的项目表中选择项目,对其进行排序,然后通过联接来获取品牌和类别。

可以在单个查询中编写,如下所示:

DB::table('items')
    ->join('brands', 'items.brand_id', '=', 'brands.id')
    ->join('categories', 'brands.category_id', '=', 'categories.id')
    ->select('brands.name as brand', 'categories.name as category')
    ->where('brands.status', 1) // as per your query
    ->whereRaw(YEAR(items.selling_date) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)) // year condition
    ->whereRaw(MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)) // last month condition
    ->orderBy('items.in_stock', 'desc') // orderBy the sales
    ->distinct() // Since you only require brand names and category names, choosing distinct will avoid the need of the GROUP BY eliminating the multiple occurances of a brand in the items table
    ->get()

我尚未尝试运行此查询,但希望对您有所帮助。如果我误解了这个问题,请随时纠正我。

相关问题