RT 场景是这样的:
Mission 表存任务
{
id,
count 最大订单数
}
Order 表存订单
{
user, 接单用户
status 订单状态 分别有 created 、 processing 、 finished 、 canceled
}
一个用户接受一个任务 就新增一份订单 状态为 created
任务订单数(条件为 status 必须为 created 、 processing 、 finished) 任务订单完成数(条件为 status 必须为 finished)
这个时候要获取条件 (任务订单数 <= Mission.count) 的任务列表
RT
暂时就想到这三个
Ps: 在发这个帖子之前我是有做过一定量相关查询的,但是由于关键字用的不好、英语不好查不到太多国外例子等原因导致我并没有找到任何方案 所以想发个帖子讨论一下 如果能有相关的链接(中英都可以)也可以发上来学习一下 最好是有相关有质量的开源项目可以做参考
PPs: 排版比较辣鸡轻喷。一定抽空学 MarkDown
// Mission Model
class Mission extends ActiveRecord
{
public $complete_count;
public $order_count;
...
public function rules()
{
return [[['id', 'count'], 'safe]];
}
public function getOrders()
{
return $this->hasMany(Order::className(), ['mission_id' => 'id']);
}
....
}
// Order Model
class Order extends ActiveRecord
{
const STATUS_CREATED = 0;
const STATUS_COMPLETE = 1
const STATUS_PROCESSING = 2;
const STATUS_FAILED = 3
const STATUS_CANCELED = 4;
public function rules()
{
return [
[['user', 'mission_id', 'status'], 'safe']
];
}
public function getMission()
{
return $this->hasOne(Mission::className(), ['id' => 'mission_id']);
}
public function getUser()
{
return $this->hasOne(User::className(), ['id' => 'user']);
}
public function find()
{
return new OrderQuery(get_called_class());
}
}
// User Model
class User extends ActiveRecord
{
public function rules()
{
return [['id', 'safe']];
}
}
// Order Query
class OrderQuery extends ActiveQuery
{
public function status($status)
{
return $this->andWhere(['status' => $status]);
}
}
// 截止睡觉前想到我的写法
public function actionA()
{
$missionQuery = Mission::find()->alias('mission');
$missionQuery->leftJoin(Order::tableName() . ' order', '`order`.mission_id = mission.id');
// Count Query
$missionCountQuery = Order::find()->alias('order')->select(new Expression('count(*)'))->where('`order`.mission_id = `mission`.id')->status([Order::STATUS_COMPLETE, Order::STATUS_PROCESSING]);
// where (select...) < mission.count
$missionQuery->andWhere('(' . $missionCountQuery->createCommand()->sql . ') < mission.count');
$data = $missionQuery->all();
return $data;
}
// 发帖前的写法
public function actionB()
{
$query = MissionPlatform::find()->alias('p')->select('*')->orderBy('id desc');
$missionOrderCountQuery = Order::find()->select(['count' => new Expression('count(*)')])->alias('o');
$missionCompleteCountQuery = clone $missionOrderCountQuery;
$query->addSelect([
'order_count' => $missionOrderCountQuery->where('o.mission_id = p.id'),
'complete_count' => $missionCompleteCountQuery->where('o.mission_id = p.id and o.status in :status', [':status' => [Order::STATUS_COMPLETE, Order::STATUS_PROCESSING]])
]);
// 通过having过滤
$query->andHaving('complete_count < p.count');
$data = [];
foreach($query->each(100) as $mission)
{
$tmp = $mission->toArray(['id', 'count']);
$tmp['order_count] = $mission->order_count;
$tmp['complete_count'] = $mission->complete_count;
$data[] = $tmp;
}
return $data;
}
/**
我承认脑子一抽扔了优雅俩字到帖子标题上 实际却像是跟别人要成品,
因为发帖的时候刚熬完夜,所以还没整理代码就睡着了,我也是发完才想起来应该扔份代码
但是因为自己写的实际代码要比帖子上举例的更复杂(更无用)一点,所以就没贴上,起来发现被喷了,确实是我的不对
希望各位大佬不要嫌弃小菜给小菜提点建议
Ps:
1. 由于本人是个数据库弱痴,所以连查都无从下手的,如果更好的解决办法是关于数据库方面的 希望能不嫌弃丢我两个相关关键词
2. 关于表关联关系 上述的模型定义应该能看的懂的吧
3. 我上面的 $missionCountQuery->createCommand()->sql 方式我认为特别不合适。暂时没深入了解这块就没继续改(因为发帖的时候我还在赶这个东西)
4. rules 定义希望不要吐槽,我实际写模型不会这么写的,只是瞎写一下确保有那么几个字段就好了
**/
1
young 2017-04-15 08:40:13 +08:00
增加几个计数字段不可以吗?
|
2
qce7 2017-04-15 09:16:11 +08:00
两个表关联关系,外键都没有,别人怎么给你回答
|
3
bombless 2017-04-15 09:19:19 +08:00 via Android
看标题说有没有更优雅的写法我还以为已经写了一版让人来改呢……结果是还没写想要别人写现成的是吧……
|
4
reus 2017-04-15 14:15:46 +08:00
你根本就是不会!
|
5
Mitt OP |
6
Mitt OP @reus 虽然我用这框架也有一段时间了,但是确实不敢承认自己会这框架,写的几个项目都是堆代码到控制器里的,我自己看的都恶心。以我的现在的水平直接看框架源码确实有些看不懂,所以我更倾向看成品源码去学习深入框架的各种用法
|
8
Mitt OP @miaotaizi 其实我发这帖子之前就已经 Google 了很长时间了(至少 6 个小时) 因为我自己搜的关键词大多是中文 英文极少数 搜出来的大多是新手教程 不是我想要的,所以才想来这里发帖讨论一下对于一种场景大家是怎么做的, 对于伸手 我也认同你的观点 但是我不认为我是纯粹的伸手党,如果你真的看了我的帖子 那你应该知道 我更想要的是相关文档 帖子 链接 关键词 , 特别是关键词 我认为我不是不善用 Google 而是没有正确使用合适的关键词 所以找出来一大堆不相干的东西,“看着恶心就想办法让他不恶心” 这是我发这个帖子是目的之一。可能我说这句话不太合适,但是我需要的是别人的“指引”。 // 以上语句表述没有恶意成分
|
11
cszchen 2017-04-16 08:14:47 +08:00
你的表有哪些字段都没说清楚,看了你的代码才大概知道你的表还有哪些字段,好累,这样不好,还是应该贴完整点的。
另外不要想着一个方法搞定所有的事,一个方法就只应该完成一件事,这样就很容易实现了,也才优雅。 |
12
cszchen 2017-04-16 08:16:49 +08:00
比如在 Order Model 里增加一个静态方法,返回特定任务特定状态的数量
controller 中调用和并做一下加减运算,即能复用,又很简单 |
13
Mitt OP |
15
qce7 2017-04-17 09:23:10 +08:00
可以考虑在 mission 中加几个字段,任务订单数,任务订单完成数
这样所有的问题都简化了 |