Skip to content

[Bug]: Export from query creates a file with duplicate rows when the query contains an aggregate function #4336

@hoan-anh

Description

@hoan-anh

Is the bug applicable and reproducable to the latest version of the package and hasn't it been reported before?

  • Yes, it's still reproducable

What version of Laravel Excel are you using?

3.1.67

What version of Laravel are you using?

12.19.3

What version of PHP are you using?

8.3

Describe your issue

When using export with FromQuery concerns, and you add an aggregate functionto the SELECT clause of the query like:
DB::raw('SUM(amount) AS amount')
The exported file will have some duplicate rows if the query returns a large number of records (in my case it was ~8k).
If I remove the aggregate function, the exported file doesn't contains any duplicates.

How can the issue be reproduced?

Use export with the FromQuery, WithMapping concerns, and in the query, add an aggregate function like SUM()
Example:

class PayrollDeductionsExportTicoFormat implements FromQuery, WithMapping, WithCustomCsvSettings
{
    use Exportable;

    protected ?string $employee_code;

    protected ?Carbon $endDate;

    protected ?Carbon $startDate;

    public function __construct(?string $employee_code, ?Carbon $startDate, ?Carbon $endDate)
    {
        $this->employee_code = $employee_code;
        $this->startDate = $startDate;
        $this->endDate = $endDate;
    }

    public function getCsvSettings(): array
    {
        return [
            'delimiter' => ',',
            'enclosure' => '',
            'output_encoding' => 'SJIS-win',
            'line_ending' => "\r\n"
        ];
    }

    /**
     * @param PayrollDeduction $payrollDeduction
     */
    public function map($payrollDeduction): array
    {
        return [
            $payrollDeduction->employee_code,
            $payrollDeduction->payroll_item_code,
            (new Carbon($payrollDeduction->payroll_deduction_at))->format('Y/n/j'),
            $payrollDeduction->amount,
            '3',
            '0'
        ];
    }

    public function query()
    {
        $query = PayrollDeduction::query()
            ->select(
                'employees.employee_code',
                'payroll_deductions.payroll_item_code',
                'payroll_deductions.payroll_deduction_at',
                DB::raw('SUM(payroll_deductions.amount) AS amount')
            )
            ->join('employees', 'payroll_deductions.employee_id', '=', 'employees.id')
            ->where('employees.company_id', '=', Company::TICO)
            ->whereIn('employees.employment_type_id', [
                EmploymentType::REGULAR,
                EmploymentType::FIXED_TERM
            ])
            ->whereNotIn('employees.personnel_type_id', [
                PersonnelType::PART_TIMER,
                PersonnelType::FIXED_TERM
            ]);
        
        if (isset($this->employee_code)) {
            $query->where('employees.employee_code', 'like', "%$this->employee_code%");
        }
        if (isset($this->startDate) && isset($this->endDate)) {
            $query->whereDate('payroll_deductions.payroll_deduction_at', '>=', $this->startDate)
                ->whereDate('payroll_deductions.payroll_deduction_at', '<=', $this->endDate);
        }

        $query->groupBy('employee_code', 'payroll_item_code', 'payroll_deduction_at')
            ->orderBy('payroll_deduction_at');

        return $query;
    }
}

What should be the expected behaviour?

It should not exports duplicate rows.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions