SELECT paybacks.id as payback_id, paybacks.booking_id, bookings.status, paybacks.success, bookings.id as booking_id FROM `bookings` LEFT JOIN `paybacks` ON `paybacks`.`booking_id` = `bookings`.`id` WHERE (bookings.status = 1) AND (paybacks.success = true)
在Rails中
Booking.where("bookings.status = 1").joins("LEFT JOIN `paybacks` ON `paybacks`.`booking_id` = `bookings`.`id`").select("paybacks.points_to_redeem as payback_points_used").where("paybacks.success = true" ).select("bookings.id as booking_id")
我在预订表中有1659行,但只有800行。请帮助我。
答案 0 :(得分:3)
您必须将第二个where
条件添加到开启条件:
SELECT paybacks.id as payback_id, paybacks.booking_id, bookings.status, paybacks.success, bookings.id as booking_id FROM `bookings` LEFT JOIN `paybacks` ON `paybacks`.`booking_id` = `bookings`.`id` AND (paybacks.success = true)
WHERE (bookings.status = 1)
如果您不这样做,bookings
中paybacks
中没有记录的所有记录都将被忽略。
输入:
预订:
ID | attribute1 | attribute2
1 | xxx | yyyy
2 | yyy | zzzz
的回报:
ID | bookings_id | success
1 | 1 | true
离开加入后你就拥有了这个:
booking.ID | attribute1 |attribute2 | paybacks.ID | bookung_id | success
1 | xxx | yyyy | 1 | 1 | true
2 | yyy | zzzz | null | null | null
如果你在where语句中有success = true
,你将忽略第二行,因为
success is null
答案 1 :(得分:2)
让我们举一个例子说明这一点。 当我们离开连接条件时,它会在连接后过滤记录。
让我们说我们有2张桌子
mysql> select * from test1;
+------+------+--------+
| id | val | status |
+------+------+--------+
| 1 | a | 0 |
| 2 | b | 1 |
| 3 | c | 1 |
| 4 | d | 1 |
| 5 | d | 0 |
+------+------+--------+
5 rows in set (0.00 sec)
mysql> select * from test2 ;
+------+------+------+
| id | t1id | val |
+------+------+------+
| 1 | 1 | aaa |
| 2 | 2 | aaa |
| 3 | 3 | aaa |
| 4 | 5 | eeee |
+------+------+------+
4 rows in set (0.00 sec)
如果我们需要从test1获取所有数据并通过执行left join
到test2,它将返回test1中的所有数据和test2中的非匹配记录为null
select t1.*,
t2.t1id from
test1 t1 left join test2 t2 on t1.id = t2.t1id ;
+------+------+--------+------+
| id | val | status | t1id |
+------+------+--------+------+
| 1 | a | 0 | 1 |
| 2 | b | 1 | 2 |
| 3 | c | 1 | 3 |
| 4 | d | 1 | NULL |
| 5 | d | 0 | 5 |
+------+------+--------+------+
现在,如果我们添加where条件,它将在连接后过滤数据
select t1.*,
t2.t1id
from test1 t1
left join test2 t2 on t1.id = t2.t1id where t1.status = 1;
+------+------+--------+------+
| id | val | status | t1id |
+------+------+--------+------+
| 2 | b | 1 | 2 |
| 3 | c | 1 | 3 |
| 4 | d | 1 | NULL |
+------+------+--------+------+
甚至
select t1.*,
t2.t1id from test1 t1
left join test2 t2 on t1.id = t2.t1id
where t2.val = 'aaa'
+------+------+--------+------+
| id | val | status | t1id |
+------+------+--------+------+
| 1 | a | 0 | 1 |
| 2 | b | 1 | 2 |
| 3 | c | 1 | 3 |
+------+------+--------+------+
现在,如果我们想要显示左表数据,那么我们需要将where条件移动到连接条件,结果不匹配的记录将显示为null。
select t1.*,
t2.t1id from test1 t1
left join test2 t2 on t1.id = t2.t1id
and t1.status = 1 and t2.val = 'aaa'
+------+------+--------+------+
| id | val | status | t1id |
+------+------+--------+------+
| 1 | a | 0 | NULL |
| 2 | b | 1 | 2 |
| 3 | c | 1 | 3 |
| 4 | d | 1 | NULL |
| 5 | d | 0 | NULL |
+------+------+--------+------+
因此,在您的情况下,如果您希望左表中的所有记录都在结果中,则必须将where条件移动到连接条件。
答案 2 :(得分:1)
我得到了答案。请检查以下查询。我在and
条件下添加了join
。它给了我确切的答案。
SELECT bookings.id as booking_id, paybacks.points_to_redeem as payback_points_used FROM `bookings` LEFT JOIN `paybacks` ON `paybacks`.`booking_id` = `bookings`.`id` and paybacks.success = true WHERE (bookings.status = 1) GROUP BY paybacks.booking_id