SQLite 值到结果数组中

Posted

技术标签:

【中文标题】SQLite 值到结果数组中【英文标题】:SQLlite values into result array 【发布时间】:2021-04-06 04:41:28 【问题描述】:

我有两个 SQL 数据库表。如何从数据中获取结果数组?因为它应该是一个用于standardDevation函数的等级数组。 据我了解,如果名称是唯一的并且我需要每个人的成绩列表,它应该看起来像这样 ['Alice' => [5, 4, 5], 'Bob' => [2]] 。 准备语句已完成,但问题出在第一个 foreach 循环中。

Student table(id INTEGER PRIMARY KEY, name VARCHAR(255) UNIQUE);
Grade table(id INTEGER, grade INTEGER);

Student table     Grade table
id   name          id    grade
1   Alice           1      5
2   Bob             1      4
3   Carol           1      5
                    2      4
require_once 'functions.php';

$conn = getConnectionWithData('data.sql');

$stmt = $conn->prepare('select * from student inner join grade on grade.id = student.id' );

$stmt->execute();

$result = [];

foreach ($stmt as $row)
    $name = $row['name'];
    if(isset($result[$row['name']]))
        $result[$name] = [$row['grade']];
    else
        $result[$name] = [$row['grade']];
    


foreach ($result as $name => $grades) 
    $std = standardDeviation($grades);
    print "$name: $std\n";

【问题讨论】:

【参考方案1】:

与您的代码非常相似,但 SQL 不同:

-- SQLite syntax
select student.name, group_concat(grade.grade, ',') as grades
from student
inner join grade on grade.id = student.id
group by student.name

PHP 代码:

require_once 'functions.php';
$conn = getConnectionWithData('data.sql');

// Extract grades as a comma-separated list of values per student in SQL
$sql = "select name, group_concat(grade, ',') grades from student inner join grade on grade.id = student.id group by name";
// There is no need to prepare a non-parameterized query
$results = $conn->query($sql);

foreach ($results as $result)

 // Make an array out of the comma-separated list of values before calling standardDeviation
 $std = standardDeviation(implode(',', $result['grades']));
 print "$result['name']: $std\n";

 

【讨论】:

【参考方案2】:

您可以直接在查询中实现逻辑。 SQL 是一种基于集合的语言,可以高效地聚合数据。

在 SQLite 中,您可以使用group_concat() 进行字符串聚合。我发现子查询在这里很方便:

select s.*,
    (
        select '[' || group_concat(g.grade) || ']'
        from grade g
        where g.id = s.id
    ) as grades
from students s

如果您想过滤掉根本没有成绩的学生,那么加入是一种更好的方法:

select s.*, g.grades
from students s
inner join (
    select id, 
        '[' || group_concat(grade) || ']' as grades
    from grade g
    group by id
) g on g.id = s.id

【讨论】:

我能以某种方式只使用 foreach 吗?由于我们只在考试中使用过一次,并且几乎一直使用 mysql,所以我担心它会太复杂而无法记住:D

以上是关于SQLite 值到结果数组中的主要内容,如果未能解决你的问题,请参考以下文章

我可以从节点中的 sqlite3 数据库中获取数组而不是 JSON 数组的结果吗?

sqlite 能存储数组和集合吗

使用 Gson 解析后将嵌套的 JSON 数组插入 SQLite

sqlite 判断表中字段是不是存在

Sqlite:在子查询“消除”结果中排序

使用 Blob 在 SQLite 中存储字节数组