简体   繁体   中英

Laravel 5 - Retrieve the first 4 records for each category in database

I have a database table of gallery images which are categorised by the following:

'corporate', 'food', 'park', 'parties', 'rides', 'schools', 'venue'

Each image has one of these categories assigned to it.

I'm building a main gallery page in which I want to display the latest 4 images from each of these categories in the database.

Could someone assist as to how I can go about building the query?

The query starts as follows:

Bugz\GalleryImage::

Table Structure

Schema::create('gallery_images', function (Blueprint $table) {

            //set the table engine:
            $table->engine = 'InnoDb';

            //define an auto-incrementing primary key:
            $table->increments('id');

            //define the general fields:
            $table->enum('gallery', array('corporate', 'food', 'park', 'parties', 'rides', 'schools', 'venue'))->default('corporate');
            $table->string('title');
            $table->string('content')->nullable()->default(null);

            //define the audit fields:
            $table->timestamps();
            $table->softDeletes();

        });

I don't have enough experience yet with Eloquent to write more complex queries.

Thank you.

Here's one way...

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(image_id INT NOT NULL ATO_INCREMENT PRIMARY KEY
, category ENUM('corporate', 'food', 'park', 'parties', 'rides', 'schools', 'venue') NOT NULL
);

INSERT INTO my_table (category) VALUES
('corporate'), 
('food'), 
('park'), 
('parties'), 
('rides'), 
('schools'), 
('venue'),
('rides'), 
('schools'), 
('venue'),
('food'), 
('park'), 
('parties'), 
('rides'), 
('corporate'), 
('food'), 
('park'), 
('food'), 
('park'), 
('parties'), 
('rides'), 
('food'), 
('park'), 
('food'), 
('corporate'), 
('rides'), 
('corporate'), 
('parties'), 
('rides'), 
('corporate'), 
('food'),
('schools'), 
('venue'),
('venue'),
('food'), 
('park'), 
('parties')
;

Intermediate result...

SELECT x.*
     , COUNT(y.image_id) temp_ranks_for_y
  FROM my_table x 
  JOIN my_table y   
    ON y.category = x.category 
   AND y.image_id >= x.image_id 
 GROUP 
    BY x.image_id;
+----------+-----------+-------------------+
| image_id | category  | temp_ranks_for_y  |
+----------+-----------+-------------------+
|        1 | corporate |                 5 |
|        2 | food      |                 8 |
|        3 | park      |                 6 |
|        4 | parties   |                 5 |
|        5 | rides     |                 6 |
|        6 | schools   |                 3 |
|        7 | venue     |                 4 |
|        8 | rides     |                 5 |
|        9 | schools   |                 2 |
|       10 | venue     |                 3 |
|       11 | food      |                 7 |
|       12 | park      |                 5 |
|       13 | parties   |                 4 |
|       14 | rides     |                 4 |
|       15 | corporate |                 4 |
|       16 | food      |                 6 |
|       17 | park      |                 4 |
|       18 | food      |                 5 |
|       19 | park      |                 3 |
|       20 | parties   |                 3 |
|       21 | rides     |                 3 |
|       22 | food      |                 4 |
|       23 | park      |                 2 |
|       24 | food      |                 3 |
|       25 | corporate |                 3 |
|       26 | rides     |                 2 |
|       27 | corporate |                 2 |
|       28 | parties   |                 2 |
|       29 | rides     |                 1 |
|       30 | corporate |                 1 |
|       31 | food      |                 2 |
|       32 | schools   |                 1 |
|       33 | venue     |                 2 |
|       34 | venue     |                 1 |
|       35 | food      |                 1 |
|       36 | park      |                 1 |
|       37 | parties   |                 1 |
+----------+-----------+-------------------+

So...

SELECT x.* 
  FROM my_table x 
  JOIN my_table y 
    ON y.category = x.category 
   AND y.image_id >= x.image_id 
 GROUP 
    BY x.image_id 
HAVING COUNT(y.image_id) <=4 
 ORDER 
    BY category 
     , image_id DESC;
+----------+-----------+
| image_id | category  |
+----------+-----------+
|       30 | corporate |
|       27 | corporate |
|       25 | corporate |
|       15 | corporate |
|       35 | food      |
|       31 | food      |
|       24 | food      |
|       22 | food      |
|       36 | park      |
|       23 | park      |
|       19 | park      |
|       17 | park      |
|       37 | parties   |
|       28 | parties   |
|       20 | parties   |
|       13 | parties   |
|       29 | rides     |
|       26 | rides     |
|       21 | rides     |
|       14 | rides     |
|       32 | schools   |
|        9 | schools   |
|        6 | schools   |
|       34 | venue     |
|       33 | venue     |
|       10 | venue     |
|        7 | venue     |
+----------+-----------+
27 rows in set (0.00 sec)

This code will retrives 4 images of every category. if you want to retrive latest one then just add sort by cluse in outer query.

    DB::table('gallery_images AS GI')
    ->where(function($query)
        {
            DB::table('tbl_dept_master AS GI2')
            ->select(DB::raw(count(1)))
            ->from('gallery_images As GI2')
            ->where('GI2.gallery','=','GI.gallery')
            ->where('GI2.title','>=','GI.title');
        })
    ->get();

If need more help comment. Hope this will sovle your problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM