Laravel-Excel icon indicating copy to clipboard operation
Laravel-Excel copied to clipboard

[BUG] FromQuery - Sort Bug Showing Duplicated Data

Open RetailAid opened this issue 3 years ago • 4 comments

Versions Laravel version: 6.2 Php version: 7.4.16 Laravel-Excel version: 3.1.27

Description: When using FromQuery to do a custom query and using the sort function on the Eloquent object (users table), some of the rows are duplicated.

Expected behaviour: All the relevant rows in the database should show correct data. Users in the table are unique.

Code screenshot First line produces incorrect result 2nd line produces correct data with no duplicates. image

The code is part of an UsersExport class which implements FromQuery, WithHeadings, WithMapping

RetailAid avatar Mar 23 '21 07:03 RetailAid

I think this is because we use chunk() instead of chunkById I'm not sure if we can just switch that.

patrickbrouwers avatar May 30 '21 15:05 patrickbrouwers

Hi,

Laravel: 8.56.0 PHP: 8.0 Laravel-Excel: 3.1.30

We see the same behaviour with randomly duplicate rows with large data.

eldor avatar Aug 26 '21 06:08 eldor

Same issue here. Confirmed that chunking is the issue. Issue is resolved when set chunk size > # rows.

rderks88 avatar Apr 06 '22 17:04 rderks88

Hello,

Versions Laravel version: 9.19 Php version: 8.1 Laravel-Excel version: 3.1.40

Same issue here. I generated 5 exports with "orderBy" in query, records in all of them were scrambled and 1 export contained duplicates. I generated 5 exports removing the "orderBy" and all of them contained data in same order and no duplicate records found.

N3OGeorgy avatar Sep 16 '22 12:09 N3OGeorgy

Same issue also for me, with Laravel-Excel version 3.1.44. Configuration is the same of @N3OGeorgy

gioacchinopoletto avatar Oct 19 '22 10:10 gioacchinopoletto

This is actually normal, if you run this same query with pagination, it will return random rows, because the order clause is not producing a unique value for each row, so mysql will return all the rows with the exact same value in whatever order it wants, you simply need to add a second order by clause on an unique column

You need to ->orderBy('membership_start', 'desc')->orderBy('id')

Possibly we could add an orderBy key to the given query if we don't find it already, but if it's already ordering by a unique key that is not primary it might come at a performance cost on the query

In laravel's chunk method you'll find

    /**
     * Add a generic "order by" clause if the query doesn't already have one.
     *
     * @return void
     */
    protected function enforceOrderBy()
    {
        if (empty($this->query->orders) && empty($this->query->unionOrders)) {
            $this->orderBy($this->model->getQualifiedKeyName(), 'asc');
        }
    }

So I'd just classify it as undesired behavior and a bug of mysql and not this lib, leave it as is and add a note in the doc about the fact the orderBy of FromQuery must be unique if you don't want skipped rows and duplicated rows

Tofandel avatar Sep 08 '23 21:09 Tofandel