如何写出这个多表关联查询 [ 2.0 版本 ]
有5张数据表:
会员表 member
CREATE TABLE member (
id int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
name varchar(128) NOT NULL COMMENT '名字',
created_at int(11) DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='会员'
课程表 course
CREATE TABLE course (
id int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
name varchar(128) NOT NULL COMMENT '课程名称',
created_at int(11) DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='课程'
考试表 exam
CREATE TABLE exam (
id int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
name varchar(128) NOT NULL COMMENT '名称',
created_at int(11) DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='考试'
下载资源 resource
CREATE TABLE resource (
id int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
name varchar(128) NOT NULL COMMENT '名称',
created_at int(11) DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='考试'
订单表 order
CREATE TABLE `order` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`type` int(11) NOT NULL COMMENT '会员ID',
`goods_id` int(11) NOT NULL COMMENT '商品ID',
`member_id` int(11) NOT NULL COMMENT '用户ID',
`credit` int(11) NOT NULL COMMENT '积分值',
`created_at` int(11) DEFAULT NULL COMMENT '变更时间',
PRIMARY KEY (`id`),
KEY `fk_order_owner` (`member_id`),
CONSTRAINT `fk_order_owner` FOREIGN KEY (`member_id`) REFERENCES `member` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=90 DEFAULT CHARSET=utf8mb4 COMMENT='订单表'
其中,订单表保存了课程、考试、资源的订单,具体说Order订单表各字段:
id: 主键
type: 类型,1为课程订单,2为考试订单, 3为资源订单
goods_id: 商品id
在type == 1时,该字段值为course.id;
在type == 2时,该字段值为exam.id;
type == 3时,该字段值为resource.id
user_id: 用户id
现在的需求:在订单管理功能中能够根据商品的名称搜索出对应订单
这里商品的名称根据订单的类型不同,可能是课程名称、考试名称、资源名称。
手写能实现预期效果SQL语句(查询关键词为:名):
`SELECT *`
`FROM order`
`LEFT JOIN course ON order.goods_id = course.id AND order.type =1`
`LEFT JOIN exam ON order.goods_id = exam.id AND order.type =2`
`LEFT JOIN resource ON order.goods_id = resource.id AND order.type =3`
`WHERE course.name like '%名%' or exam.name like '%名%' or resource.name like '%名%'`
如果在OrderSearch.php中用AR该怎么写呢,特别是像
LEFT JOIN course ON order.goods_id = course.id AND order.type =1
这样的关联条件,Yii2是不是不支持?
// $query->joinWith('exam')
// ->joinWith('course')
// ->joinWith('resource');
共 3 个回答
-
支持的,
比如你Order模型里定义了:public function getCourse(){ return $this->hasOne(Course::className(),['id'=>'goods_id']) ->onCondition(['type'=>1]); }
那你query里就可以用
$query->joinWith('course');
如果你要按course的name来搜索,可以用函数回调,比如:
$query->innerJoinWith([ 'course' => function ($query) { $query->andFilterWhere(['like', 'name', $this->coupon_name]); } ]);
共 2 条回复 -
yy15527726335 回答于 2018-08-20 15:27 举报
试下leftJoin('course' , 'order.goods_id = course.id AND order.type =1')....这种写法。个人想法
-
我觉得你的数据库设计让简单的问题复杂化了,课程、考试和下载资源三个表都属于商品,放在一个表格(假设叫 item )内存储就行了。把
order.type
迁移到 item 表内,整个结果会更清晰一些。共 2 条回复
Jason571
注册时间:2016-01-04
最后登录:2018-10-12
在线时长:6小时8分
最后登录:2018-10-12
在线时长:6小时8分
- 粉丝1
- 金钱30
- 威望0
- 积分90