【问题标题】:Can I do a treatement of returning values directly in SQL query我可以直接在 SQL 查询中处理返回值吗
【发布时间】:2016-05-12 09:07:26
【问题描述】:

我想知道 SQL 查询是否可以使用 SQL 中的某些条目返回数据。对不起,如果它不明确(这里不是英语,我猜你想通了),让我们看一个例子:

$req = $bdd->prepare('SELECT u.u_id, u.u_name, um.um_id, um.um_name, um.um_value
FROM users as u
LEFT JOIN users_metas as um ON um.um_uid = u.u_id');
$prepare->execute();
$datas = $prepare->fetchAll();

所以在这里,我将在$datas 中有一个类似的数组

$datas = array(
 0 =>
  u_id => 1
  u_name => name
  um_id => 1
  um_name => meta_name1
  um_value => meta_value1
 1 =>
  u_id => 1
  u_name => name
  um_id => 2
  um_name => meta_name2
  um_value => meta_value2
 ...
);

我想要的是这样的:

$datas = array(
 0 =>
  u_id => 1
  u_name => name
  meta_name1 => meta_value1
  meta_name2 => meta_value2
 1 =>
  u_id => an other user
  ...
);

在我手动处理 $datas 之后,我已经有了这个,但我想知道我是否可以在没有处理的情况下仅使用 SQL 来完成此演示文稿?

希望你们能理解我,如果你们有什么问题,我会尽力说清楚。

问候。

【问题讨论】:

    标签: php mysql sql fetchall


    【解决方案1】:

    MySQL 解决方案

    通过将表中的一列中的唯一值转换为输出中的多列,将表值表达式转换为表称为数据透视。与其他一些 DBMS 不同,MySQL 没有 PIVOTCROSSTAB 函数,因此您无法编写一个万能的解决方案来解决这个问题。

    如果您事先知道um_name 的所有可能值,则可以使用聚合函数来模拟这种行为。

    SELECT u.u_id, u.u_name,
    MAX(CASE WHEN um_name = 'meta_name1' THEN um_value END) meta_name1,
    MAX(CASE WHEN um_name = 'meta_name2' THEN um_value END) meta_name2
    FROM users as u
    LEFT JOIN users_metas as um ON um.um_uid = u.u_id
    GROUP BY u.u_id, u.u_name;
    

    此解决方案的缺点是您必须不断将MAX(CASE WHEN um_name = '...' THEN um_value END) 列添加到查询中,以获取um_name 的每个可能值。

    理论上,您可以通过首先选择所有不同的 um_name 值在 PHP 中生成此查询,但这不会使您的代码更简单或更快,因此没有什么意义。

    PHP 解决方案

    作为替代方案,只需几行 PHP 即可将您当前的输出从 fetchAll() 转换为您想要的格式。

    $out = [];
    array_walk($datas, function($v) use(&$out) {
        $out[$v["u_id"]] = (isset($out[$v["u_id"]]) ? $out[$v["u_id"]] : [])
            + ["u_id" => $v["u_id"],
               "u_name" => $v["u_name"],
               $v["um_name"] => $v["um_value"]];
    });
    $out = array_values($out);
    

    如果记录在users_metas 表中不存在,则不会设置键,因此如果不是所有用户都存在特定值,则需要在访问特定值之前检查isset

    【讨论】:

    • 非常感谢这个答案,因为我怀疑没有办法直接在 SQL 查询中做我想做的事^^! (因为我无法确定 metas 的编号和名称) 我已经在 PHP 中进行了处理,但感谢那些行!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-04
    • 2014-03-29
    • 1970-01-01
    • 1970-01-01
    • 2018-03-18
    相关资源
    最近更新 更多