我有2个表events_users: 其中存储有关参加某些活动的人的信息。许多人参加了许多活动,因此使用这个链接表。
+--------+---------+---------+
| eid | user_id | slot_no |
+--------+---------+---------+
| event1 | user1 | 0 |
| event1 | user2 | 1 |
| event2 | user3 | 0 |
+--------+---------+---------+
和events_user_score: 其中记录了事件中不同分数的人。在不同的事件中,可能有许多不同的分数类型,这就是为什么它在自己的表中,而不是在第一个表中的列
+--------+---------+------------+--------+
| eid | user_id | score_type | number |
+--------+---------+------------+--------+
| event1 | user1 | 1 | 4 |
| event1 | user1 | 2 | 3 |
| event2 | user3 | 1 | 6 |
| event1 | user1 | 2 | 5 | <- this row could not exist as
+--------+---------+------------+--------+ no duplicates possible with same eid, user_id & score_type
我希望能够根据第二个表中的数字对第一个表的选择进行排序。因此,我希望得到一个能够得到这样结果的联合工作。实际上将score_type转换为列,并将数字作为值。
+--------+---------+---------+---+---+
| eid | user_id | slot_no | 1 | 2 |
+--------+---------+---------+---+---+
| event1 | user1 | 0 | 4 | 3 |
| event1 | user2 | 1 | | |
| event2 | user3 | 0 | 6 | |
+--------+---------+---------+---+---+
到目前为止,我已尝试使用laravel的“hasMany”,但我无法使用该技术进行排序。所以我正在尝试尝试某种类型的左连接,但是真的很困惑,因为现在我没有得到任何分数:
$attendees = Events_user::whereIn("events_users.eid", $lastWeeksEvents->pluck('eid'))->where("slot_no",">=",0)
->leftJoin('event_user_score', function ($join) {
$join->on('events_users.eid', '=', 'event_user_score.eid')
->where('events_users.uid', '=', 'event_user_score.uid');
})
->get();
假设$lastWeeksEvents
返回一个事件列表,其中eid与第一个表中的事件匹配。
编辑 - 即使它们是score_types 1 - 6.让我们坚持只是尝试获得类型1&amp;列为2列。如果这更容易吗?
答案 0 :(得分:0)
要获得所需的结果,您可以在纯SQL中编写以下内容
select e1.*,
max(case when e2.score_type =1 then e2.number else 0 end ) score_type1,
max(case when e2.score_type =2 then e2.number else 0 end ) score_type2
from events_users e1
left join events_user_score e2 on e1.eid = e2.eid
and e1.user_id = e2.user_id
group by e1.eid, e1.user_id,e1.slot_no
上述查询假设可以有两个score_types为1&amp; 2如果有更多上述查询对于这种类型的结果集是不可行的。
使用laravel的查询构建器可以写成。
$attendees = Events_user::from('events_users as e1')
->select(DB::raw("e1.*,max(case when e2.score_type =1 then e2.number else 0 end ) score_type1, max(case when e2.score_type =2 then e2.number else 0 end ) score_type2"))
->leftJoin('events_user_score as e2', function ($join) {
$join->on('e1.user_id', '=', 'e2.user_id');
})
->groupBy('e1.eid')
->groupBy('e1.user_id')
->groupBy('e1.slot_no')
->get();
上述解决方案通过匹配事件和用户将events_users
表连接到您的第二个表events_user_score
。聚合被调用以获得每个eid的唯一数据,user_id&amp; SLOT_NO
答案 1 :(得分:0)
您还可以使用子查询,如下所示:
纯SQL:
select u.eid, u.user_id, u.slot_no,
(select number from events_user_score s where s.eid = u.eid and s.user_id = u.user_id and s.score_type = 1) as `1`,
(select number from events_user_score s where s.eid = u.eid and s.user_id = u.user_id and s.score_type = 2) as `2`
from events_users u
现在,在Laravel中使用它:
//Get all score types
$score_types = DB::table('events_user_score')
->select('score_type')
->groupBy('score_type')
->get();
$event_query = Events_user::from(DB::raw('events_users u'))
->select('eid', 'user_id', 'slot_no');
//Add score types as sub queries
foreach ($score_types as $score) {
$event_query->addSelect(DB::raw('(select number from events_user_score s where s.eid = u.eid and s.user_id = u.user_id and s.score_type = ' . $score->score_type . ') as `' . $score->score_type . '`'));
}
//Example, to sort by score type 1
$data = $event_query->orderBy('1')->get();
请务必在代码顶部添加use DB;
。