codeigniter 4 mysql 查询生成器从自身获取子数据
codeigniter 4 mysql query builder get subdata from itself
[更新]
错误现在消失了,但是来自 codeigniter 4 查询构建器的数据结果都具有相同的 id
值,这与 phpmyadmin 中的不同。如果我使用 $builder
方法,它现在会给出预期的结果,但我仍然希望能够尽可能正确地充分使用查询生成器..
我有一个这样的mysqltable
id | nama | hari
-----------------
1 | AAA | 1
2 | AAA | 2
3 | AAA | 3
4 | AAA | 4
5 | AAA | 5
6 | BBB | 1
7 | BBB | 2
8 | BBB | 3
当我得到一个参数id
1时,我只想得到行号1-5。当我在 phpmyadmin
中使用这个 sql 时它有效
select m.*
from m_rute m
join (
select m1.*
from m_rute m1
where m1.id = 1
) mt on mt.nama_rute = m.nama_rute
然后我尝试使用 codeigniter 4 的查询构建器“翻译”它,但是当我在邮递员上测试它时,它提供了一组数据,其中所有 id
字段都相同,这与 phpmyadmin 中的不同结果。
控制器
public function show($id = null)
{
$db = \Config\Database::connect();
$builder = $db->table('m_rute as m');
$builder->select('m.*')->where('m.id', $id);
$subquery = $builder->getCompiledSelect();
// this works but wouldn't a fully proper query builder seem nicer?
//////////////
// $builder->select('m.*')
// ->join('('.$subquery.') as m1', 'm1.nama_rute = m.nama_rute')
// ;
// $q = $builder->get();
// $data = $q->getResultArray();
$model = new MRuteModel();
$model->join('('.$subquery.') as t', 't.nama_rute = m_rute.nama_rute');
$data = $model->findAll();
if (!$data) {
return $this->failNotFound('Data not found');
}
return $this->respond($data);
}
感谢任何帮助
解决方案 1:使用 Raw/Regular Queries。
The query()
function returns a database result object when
“read” type queries are run which you can use to show your
results.
When “write” type queries are run it simply returns true
or false
depending on success or failure.
<?php
namespace App\Models;
use CodeIgniter\Model;
class MRuteModel extends Model
{
public function findById(int $id)
{
$id = $this->db->escape($id);
return $this->db->query("
select m.*
from m_rute m
join (
select m1.*
from m_rute m1
where m1.id = {$id}
) mt on mt.nama_rute = m.nama_rute")->getResultArray();
}
}
解决方案 2A:使用 SQL Joins 原始查询。
join($table, $cond[, $type = ''[, $escape = null]])
Parameters:
$table (string) – Table name
to join
$cond (string) – The
JOIN ON condition
$type
(string) – The JOIN type
$escape (bool) – Whether to
escape values and identifiers
Returns: BaseBuilder
instance (method
chaining)
Return type: BaseBuilder
Adds a JOIN
clause to a query.
<?php
namespace App\Models;
use CodeIgniter\Model;
class MRuteModel extends Model
{
public function findById(int $id)
{
$id = $this->db->escape($id);
return $this->db->table('m_rute m')
->select("m.*")
->join("
(select m1.*
from m_rute m1
where m1.id = {$id}
) mt", 'mt.nama_rute = m.nama_rute')
->get()->getResultArray();
}
}
解决方案 2B:使用 SQL Joins 和查询生成器。
Compiles a SELECT
statement and returns it as a string.
<?php
namespace App\Models;
use CodeIgniter\Model;
class MRuteModel extends Model
{
public function findById(int $id)
{
$subQuery = $this->db->table('m_rute m1')
->select("m1.*")
->where("m1.id", $id)
->getCompiledSelect();
return $this->db->table('m_rute m')
->select("m.*")
->join("($subQuery) mt", 'mt.nama_rute = m.nama_rute')
->get()
->getResultArray();
}
}
解决方案 3A:使用带闭包的 where
Clause。
where($key[, $value = null[, $escape = null]])
Parameters:
$key (mixed) – Name of field to compare, or associative array
$value (mixed) – If a single key, compared to this value
$escape
(bool) – Whether to escape values and identifiers
Returns: BaseBuilder
instance (method
chaining)
Return type: BaseBuilder
Generates the WHERE
portion of the query. Separates multiple calls with AND
.
<?php
namespace App\Models;
use CodeIgniter\Model;
use CodeIgniter\Database\BaseBuilder;
class MRuteModel extends Model
{
public function findById(int $id)
{
// With a closure.
return $this->db->table('m_rute')
->where('nama_rute =', function (BaseBuilder $builder) use ($id) {
return $builder->select("nama_rute")->from("m_rute")
->where("id", $id);
})
->get()
->getResultArray();
}
}
解决方案 3B:将 where
Clause 与生成器一起使用。
<?php
namespace App\Models;
use CodeIgniter\Model;
class MRuteModel extends Model
{
public function findById(int $id)
{
$subQuery = $this->db->table('m_rute m1')
->select("m1.nama_rute")
->where("m1.id", $id)
->getCompiledSelect();
// With a builder.
return $this->db->table('m_rute')
->where("nama_rute =($subQuery)")
->get()
->getResultArray();
}
}
[更新]
错误现在消失了,但是来自 codeigniter 4 查询构建器的数据结果都具有相同的 id
值,这与 phpmyadmin 中的不同。如果我使用 $builder
方法,它现在会给出预期的结果,但我仍然希望能够尽可能正确地充分使用查询生成器..
我有一个这样的mysqltable
id | nama | hari
-----------------
1 | AAA | 1
2 | AAA | 2
3 | AAA | 3
4 | AAA | 4
5 | AAA | 5
6 | BBB | 1
7 | BBB | 2
8 | BBB | 3
当我得到一个参数id
1时,我只想得到行号1-5。当我在 phpmyadmin
select m.*
from m_rute m
join (
select m1.*
from m_rute m1
where m1.id = 1
) mt on mt.nama_rute = m.nama_rute
然后我尝试使用 codeigniter 4 的查询构建器“翻译”它,但是当我在邮递员上测试它时,它提供了一组数据,其中所有 id
字段都相同,这与 phpmyadmin 中的不同结果。
控制器
public function show($id = null)
{
$db = \Config\Database::connect();
$builder = $db->table('m_rute as m');
$builder->select('m.*')->where('m.id', $id);
$subquery = $builder->getCompiledSelect();
// this works but wouldn't a fully proper query builder seem nicer?
//////////////
// $builder->select('m.*')
// ->join('('.$subquery.') as m1', 'm1.nama_rute = m.nama_rute')
// ;
// $q = $builder->get();
// $data = $q->getResultArray();
$model = new MRuteModel();
$model->join('('.$subquery.') as t', 't.nama_rute = m_rute.nama_rute');
$data = $model->findAll();
if (!$data) {
return $this->failNotFound('Data not found');
}
return $this->respond($data);
}
感谢任何帮助
解决方案 1:使用 Raw/Regular Queries。
The
query()
function returns a database result object when “read” type queries are run which you can use to show your results. When “write” type queries are run it simply returnstrue
orfalse
depending on success or failure.
<?php
namespace App\Models;
use CodeIgniter\Model;
class MRuteModel extends Model
{
public function findById(int $id)
{
$id = $this->db->escape($id);
return $this->db->query("
select m.*
from m_rute m
join (
select m1.*
from m_rute m1
where m1.id = {$id}
) mt on mt.nama_rute = m.nama_rute")->getResultArray();
}
}
解决方案 2A:使用 SQL Joins 原始查询。
join($table, $cond[, $type = ''[, $escape = null]])
Parameters:$table (string) – Table name to join
$cond (string) – The JOIN ON condition
$type (string) – The JOIN type
$escape (bool) – Whether to escape values and identifiers
Returns:
BaseBuilder
instance (method chaining)Return type:
BaseBuilder
Adds a
JOIN
clause to a query.
<?php
namespace App\Models;
use CodeIgniter\Model;
class MRuteModel extends Model
{
public function findById(int $id)
{
$id = $this->db->escape($id);
return $this->db->table('m_rute m')
->select("m.*")
->join("
(select m1.*
from m_rute m1
where m1.id = {$id}
) mt", 'mt.nama_rute = m.nama_rute')
->get()->getResultArray();
}
}
解决方案 2B:使用 SQL Joins 和查询生成器。
Compiles a
SELECT
statement and returns it as a string.
<?php
namespace App\Models;
use CodeIgniter\Model;
class MRuteModel extends Model
{
public function findById(int $id)
{
$subQuery = $this->db->table('m_rute m1')
->select("m1.*")
->where("m1.id", $id)
->getCompiledSelect();
return $this->db->table('m_rute m')
->select("m.*")
->join("($subQuery) mt", 'mt.nama_rute = m.nama_rute')
->get()
->getResultArray();
}
}
解决方案 3A:使用带闭包的 where
Clause。
where($key[, $value = null[, $escape = null]])
Parameters:$key (mixed) – Name of field to compare, or associative array
$value (mixed) – If a single key, compared to this value
$escape (bool) – Whether to escape values and identifiers
Returns:
BaseBuilder
instance (method chaining)Return type:
BaseBuilder
Generates the
WHERE
portion of the query. Separates multiple calls withAND
.
<?php
namespace App\Models;
use CodeIgniter\Model;
use CodeIgniter\Database\BaseBuilder;
class MRuteModel extends Model
{
public function findById(int $id)
{
// With a closure.
return $this->db->table('m_rute')
->where('nama_rute =', function (BaseBuilder $builder) use ($id) {
return $builder->select("nama_rute")->from("m_rute")
->where("id", $id);
})
->get()
->getResultArray();
}
}
解决方案 3B:将 where
Clause 与生成器一起使用。
<?php
namespace App\Models;
use CodeIgniter\Model;
class MRuteModel extends Model
{
public function findById(int $id)
{
$subQuery = $this->db->table('m_rute m1')
->select("m1.nama_rute")
->where("m1.id", $id)
->getCompiledSelect();
// With a builder.
return $this->db->table('m_rute')
->where("nama_rute =($subQuery)")
->get()
->getResultArray();
}
}