0

我有以下数据库表:

  1. 表: person 列: id, first_name, age, city, state
  2. 表: study 列: id, name, description, notes
  3. 表: person_studies 列: person_id, study_id, notes

我需要获取特定人员参与的所有研究名称:

person.id, person.first_name, person.city, study.name

这是我为获取 a 的数据而编写的查询person.id = 14

select person.id, person.first_name, study.name from person
left join person_studies on person.id = person_studies.person_id
left join study on person_studies.study_id = study.id 
where person.id=14;

由于一个人可能参与多项研究,因此我在结果集中得到了不止一行。我需要使用 Zend_Db api 来实现它。

问题是:

    1.有没有更好的方法来编写这个查询?
    2. 如果我想在单独的数组中获取 study.name 值作为结果集的一部分,是否可以在查询中这样做,这样当我在 Zend 中运行查询时:
        `$result = $this->fetchAll($select);` 
    
    其中 $select 是 sql 语句 $result 应该是以下格式:
        [0] => 数组
        (
          [person.id] => 14
          [名字] =>杰米
          [study_names] => 数组
                           (
                              [0] => 生物技术;
                              [1] => 数学;
                              [2] => 航空;
                           )
    
        )
    

任何帮助将不胜感激。

谢谢

4

2 回答 2

1

我找不到更好的方法来编写查询,但就第二个问题而言,我找到了以下使用group_concat( ) 的解决方案。

最终查询现在看起来像这样:

select person.id, person.first_name, person.city, person.state, group_concat(study.name separator '|') as studynames from person
left join person_studies on person.id = person_studies.person_id
left join study on person_studies.study_id = study.id 
where person.id=14;

我们还可以在 group_concat 中指定其他子句,例如 distinct 。有关此条款的详细说明,请参阅链接http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

于 2012-06-08T18:56:11.400 回答
0

查询看起来不错,尽管您似乎错过了其中一列(假设您实际上需要使用 person.city):

select person.id, person.first_name, person.city, study.name from person
left join person_studies on person.id = person_studies.person_id
left join study on person_studies.study_id = study.id 
where person.id=14;

代替:

select person.id, person.first_name, study.name from person
left join person_studies on person.id = person_studies.person_id
left join study on person_studies.study_id = study.id 
where person.id=14;

至于结果,我不知道有什么方法可以直接将其格式化为您想要的格式。如果你不介意一点代码,你可以尝试获取你得到的结果并格式化它们。假设您使用的是 PDO(通常与 Zend 一起使用),它看起来像这样:

$statement = $db->query(<<query from above goes here>>);
$result = $statement->fetchAll(PDO::FETCH_ASSOC);

$personStudies = array();

foreach($result as $row)
{
    $personId = $row['person.id'];
    $studyName = $row['name'];
    $personStudies[$personId]['first_name'] = $row['first_name'];
    $personStudies[$personId]['study_names'][] = $studyName;
}

foreach($personStudies as $personId=>$person)
{
    $formattedRow = array();
    $formattedRow['person.id'] = $personId;
    $formattedRow['first_name'] = $person['first_name'];
    $formattedRow['study_names'] = $person['study_names'];

    $formattedResults[] = $formattedRow;
}

并且$formattedResults应该看起来就像你指定的那样。否则,您可以分两部分进行查询:

$statement = $db->query('SELECT person.first_name FROM person WHERE person.id=14 LIMIT 1');
$person = $statement->fetch(PDO::FETCH_ASSOC);
$name = $person['first_name'];

$statement = $db->query('SELECT study.name FROM person_studies, study WHERE person_studies.study_id = study.id AND person_studies.person_id=14'); // Same as a left join
$studyNames = $statement->fetch(PDO::FETCH_COLUMN, 0);

$formattedRow = array();
$formattedRow['person.id'] = 14;
$formattedRow['first_name'] = $name;
$formattedRow['study_names'] = $studyNames;
$formattedResults[] = $formattedRow;

这应该给出相同的结果。我没有测试过代码,但它应该接近你需要的。

于 2012-06-07T00:06:28.633 回答