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

[Feature]: Cycle\Database\Query\SelectQuery::from missing "alias" parameter #200

Open
AnrDaemon opened this issue May 15, 2024 · 3 comments
Labels
type: feature New feature.

Comments

@AnrDaemon
Copy link

Is your feature request related to a problem? Please describe.

When writing complex requests, especially with subqueries, Cycle generates unusable or outright wrong SQL queries.

Example:

<?php

        $arr = $database->select([
            "id",
        ])->from(
            $this->database()->select([
                "id",
                new Fragment("COUNT(*) OVER (PARTITION BY field1, field2) AS d"),
            ])->from('a_table')
        )
            ->where("field3", "=", new Parameter(1))
            ->where("d", ">", new Parameter(1))
            ->fetchAll();

The generated query looks like

SELECT `id`
FROM (SELECT `id`, COUNT(*) OVER (PARTITION BY tag, component) AS d
FROM `a_table`)
WHERE `field3` = ? AND `d` > ?;

which looks fine, but in fact is not correct MySQL.

Describe the solution you'd like

Simply adding subquery table alias … FROM (SELECT …) AS t WHERE … fixes that in an instant.

<?php

        $arr = $database->select([
            "id",
        ])->from(
            $this->database()->select([
                "id",
                new Fragment("COUNT(*) OVER (PARTITION BY field1, field2) AS d"),
            ])->from('a_table'),
            "t"
        )
            ->where("field3", "=", new Parameter(1))
            ->where("d", ">", new Parameter(1))
            ->fetchAll();
SELECT `id`
FROM (SELECT `id`, COUNT(*) OVER (PARTITION BY tag, component) AS d
FROM `a_table`) AS `t`
WHERE `field3` = ? AND `d` > ?;

Describe alternatives you've considered

Using ->innerJoin() method with appropriate ->on() bindings works around the deficiency, but defy the code readability.

Additional context

No response

@AnrDaemon AnrDaemon changed the title [Feature]: Cycle\Database\Query\SelectQuery::from ьшыыштп "alias" parameter [Feature]: Cycle\Database\Query\SelectQuery::from missing "alias" parameter May 15, 2024
@roxblnfk roxblnfk added type: feature New feature. and removed type: feature labels May 20, 2024
@gam6itko
Copy link
Contributor

gam6itko commented Jun 11, 2024

You can achieve this with workaround below ^_^

$select->from(
    new Fragment('('.$selectSub.') AS table1'),
)

@gam6itko
Copy link
Contributor

gam6itko commented Jun 11, 2024

@roxblnfk may be we need to add some extra class for this case e.g. DerivedTable

DerivedTable

$subQuery = $this
    ->database()
    ->select([
        "id",
        new Fragment("COUNT(*) OVER (PARTITION BY field1, field2) AS d"),
    ])
    ->from('a_table');

$derivedTable = new DerivedTable(
    query: subQuery,
    alias: 't'
);

$arr = $database
    ->select(["id"])
    ->from( $derivedTable )
    ->where("field3", "=", new Parameter(1))
    ->where("d", ">", new Parameter(1))
    ->fetchAll();

CTETable

Also we can add a new feature CTETable which render sql query with with

$subQuery = $this
    ->database()
    ->select([
        "id",
        new Fragment("COUNT(*) OVER (PARTITION BY field1, field2) AS d"),
    ])
    ->from('a_table');

$cteTable = new CTETable(
    query: subQuery,
    alias: 't'
);

$arr = $database
    ->select(["id"])
    ->from( $cteTable )
    ->where("field3", "=", new Parameter(1))
    ->where("d", ">", new Parameter(1))
    ->fetchAll();
WITH t AS
(
  SELECT]
    `id`, 
    COUNT(*) OVER (PARTITION BY tag, component) AS d 
  FROM `a_table`
)
SELECT `id` FROM `t` WHERE `field3` = ? AND `d` > ?;

@roxblnfk
Copy link
Member

@gam6itko yes it is also my main idea about it

See #139 (comment)

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

No branches or pull requests

3 participants