【问题标题】:How to simplify this 2 MySQL Queries如何简化这 2 个 MySQL 查询
【发布时间】:2017-02-20 22:28:20
【问题描述】:

这一定很容易,但我不记得我以前是怎么做到的。 我正在尝试在记录 ID 匹配的查询中进行另一个查询:

/*
    tables:
      models:
        model_id
        model_name

      models_years:
        model_year_id
        model_id
        year
*/

$models = DBW::run('SELECT * FROM models', [], true);
$models_years = DBW::run('SELECT * FROM models_years', [], true);

$output = [];

foreach ($models as $model)
{
    $years = [];
    foreach ($models_years as $model_year)
    {
        if ($model_year['model_id'] == $model['model_id'])
        {
            $years[] = $model_year['year'];
        }
    }
    $output[] = [
        'model_name' => $model['model_name'],
        'years' => $years
    ];
}

var_dump( $output );

我使用 PDO(设置:ATTR_DEFAULT_FETCH_MODE = FETCH_ASSOC),并且“DBW::run”函数返回 $stmt->fetchAll()。 这只是我正在尝试做或改进的一个例子,我知道可以在一个 SQL 中完成所有这些,我以前做过但不记得了! :(

【问题讨论】:

    标签: mysql


    【解决方案1】:
    SELECT m.model_name, y.`year`
    FROM models AS m
    LEFT JOIN models_years As y ON m.model_id = y.model_id
    

    或者从您最初的问题来看,您可能需要以下内容:

    SELECT m.model_name, group_concat(y.`year`) AS `year`
    FROM models AS m
    LEFT JOIN models_years As y ON m.model_id = y.model_id
    GROUP BY 1
    

    为什么?

    1 - 连接表以减少 SQL 调用

    2 - 将结果分组(BY 1 == BY m.model_name,这里只是一个懒惰的简写)

    3 - group_concat(...) 默认生成:year1,year2,year3,... 然后如果需要,您可以使用 PHP explode(',', ...) 更改为数组

    【讨论】:

    • 谢谢!第二个正是我想要的,如果你能解释一下发生了什么,将不胜感激。
    【解决方案2】:

    加入表格,并使用GROUP_CONCAT 组合每个模型的所有年份。然后使用explode() 将其拆分为一个数组。

    $output = DBW::run('select m.model_name, GROUP_CONCAT(y.year) AS years
                        FROM models AS m
                        LEFT JOIN models_years AS y ON m.model_id = y.model_id
                        GROUP BY m.model_id', [], true);
    foreach ($output as &$row) {
        $row['years'] = explode(',', $row['years']);
    }
    

    【讨论】:

    • 感谢您的时间和精力。它只让我选择一个最好的,但这也是一个可行的答案!
    【解决方案3】:
    SELECT model_name, year FROM models, models_years WHERE 
        models.model_id=models_years.model_id
    

    或者,如果您更喜欢 JOIN 语法,

    SELECT model_name, year FROM models JOIN models_years ON 
        models.model_id=models_years.model_id
    

    【讨论】:

      【解决方案4】:

      另一种方法是使用子选择。

      select * from models where model_id in (select model_id from models_years)
      

      【讨论】:

      • 这是倒退的。原始查询将包括所有模型,这将忽略不在model_years 中的任何模型。
      • 您也没有返回年份列表。你将如何填写$years 数组?
      猜你喜欢
      • 1970-01-01
      • 2015-02-04
      • 2010-09-29
      • 1970-01-01
      • 2010-11-15
      • 1970-01-01
      • 2014-03-19
      相关资源
      最近更新 更多