Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subselect selects only 1st column and does not form from keyword #23327

Closed
webmake opened this issue Feb 28, 2018 · 6 comments
Closed

Subselect selects only 1st column and does not form from keyword #23327

webmake opened this issue Feb 28, 2018 · 6 comments

Comments

@webmake
Copy link
Contributor

webmake commented Feb 28, 2018

  • Laravel Version: 5.5.*
  • PHP Version: 7.1

Description:

How to reach properly subquery select attributes as below and add from properly?

 SELECT attribute, COUNT(*) AS items_count
                FROM (
                    SELECT attribute, attribute2
                    FROM history
                    WHERE attribute IN ('1','2','3')
                    GROUP BY attribute, attribute2
                ) subtable
                GROUP BY attribute

Steps To Reproduce:

        dd(\DB::query()
            ->select('attribute')
            ->selectRaw('COUNT(*) AS items_count')
            ->selectSub(function(Builder $query) use ($values){
                 $query->select(['attribute', 'attribute2'])
                    ->from('history')
                    ->whereIn('attribute', $values)
                    ->groupBy('attribute', 'attribute2');
            }, 'subtable')
            ->groupBy('attribute')
            ->toSql());

gives only with one and first attribute:

select `attribute`, COUNT(*) AS items_count, (select `attribute` from `history` where `attribute` in (?, ?, ?) group by `attribute`, `attribute2`) as `subtable` group by `attribute`

due this code:

    protected function parseSubSelect($query)
    {
        if ($query instanceof self) {
            $query->columns = [$query->columns[0]];
@webmake webmake changed the title Subselect selects only 1st column Subselect selects only 1st column and does not form from keyword Feb 28, 2018
@webmake
Copy link
Contributor Author

webmake commented Feb 28, 2018

Notable, this can't be replaced by

\DB::select('SELECT attribute, COUNT(*) AS items_count
                FROM (
                    SELECT attribute, attribute2
                    FROM history
                    WHERE attribute IN (?)
                    GROUP BY attribute, attribute2
                ) subtable
                GROUP BY attribute',
            $values
        )

because this returns one result, if (?) will be replaced by (?,?) - then 2results will be returned,and so on, so I am not sure how much values there will be, so expected in OOP style to build query, and get properly bindings by laravel itself, but at some point this does not work(?)

@staudenmeir
Copy link
Contributor

staudenmeir commented Feb 28, 2018

The line was added in #19013. Apparently, the PR didn't consider subqueries in the FROM part.

Laravel only uses the method in QueriesRelationships::withCount() (via selectSub()).

If we move $query->columns = [$query->columns[0]]; from Builder::parseSubSelect() to QueriesRelationships::withCount()? The tests still work.

@webmake
Copy link
Contributor Author

webmake commented Feb 28, 2018

Yeah, but that PR solves some sort of problems. Once again take a look at bolded query parts, that are not presented using selectSub

SELECT attribute, COUNT(*) AS items_count
FROM (
SELECT attribute , attribute2
FROM history
WHERE attribute IN (?, ?, ?)
GROUP BY attribute, attribute2
) subtable
GROUP BY attribute
I think this is not reachable using that function, so question remains how to reach same functionality without any hacks, such as string fill with lenght of parameters in where clause

@staudenmeir
Copy link
Contributor

Can you please take a look at this @cdstarling?

@ghost
Copy link

ghost commented Feb 28, 2018

When I created my pull request I initially tried to solve the problem in the QueriesRelationships to avoid this sort of situation in which I missed a use case for the subquery with multiple selects.

For some reason I couldn't get it to work within the withCount method but I've just tried it and it seems to work fine, so I will make a pull request for that now.

taylorotwell pushed a commit that referenced this issue Mar 1, 2018
…3357)

A previous pull request #19013, which aimed to solve the issue of multiple select statements causing an SQL error within a withCount function, assumed a sub query would only need one select statement.

This is not the case, so the code that removes excess filters is moved to the withCount method where the sub query does only need one select.
@staudenmeir
Copy link
Contributor

@laurencei Can be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants