我正在研究什么对我来说是一个复杂的查询,我已经设法获得了我需要的信息,但似乎被迫创建一个表来完成它。我正在使用MySQL,所以我不能使用WITH
,我不能使用视图,因为我的SELECT
在FROM
子句中包含子查询,我无法使用临时表因为我需要自我加入。我错过了什么吗?
背景:
reservation
可以有一个或多个reservation_detail
(reservation_id
上的外键密码reservation_detail
有一个quantity
和一个ticket_type
(ticket_type
上的外键关键字这是我当前解决方案的第一部分:
CREATE TABLE
tmp
SELECT
t.reservation_id,
t.ticket_type,
COALESCE(rd.quantity,0) AS qty
FROM (
SELECT *
FROM
(ticket_type tt, reservation r)
) t
LEFT JOIN
reservation_detail rd
ON
t.reservation_id = rd.reservation_id
AND
t.ticket_type = rd.ticket_type;
这给了我一个如下所示的表格,对于reservation_id
和ticket_type
的每个组合,我有一个qty
。
+----------------+-------------+------+
| reservation_id | ticket_type | qty |
+----------------+-------------+------+
| 1 | ADULT | 2 |
| 1 | CHILD | 2 |
| 1 | INFANT | 0 |
| 2 | ADULT | 1 |
| 2 | CHILD | 0 |
| 2 | INFANT | 0 |
| 3 | ADULT | 1 |
| 3 | CHILD | 0 |
| 3 | INFANT | 0 |
+----------------+-------------+------+
现在我可以自己加入这张桌子三次以获得我真正想要的东西......
SELECT
t1.reservation_id,
t1.qty AS num_adults,
t2.qty AS num_children,
t3.qty AS num_infants
FROM
tmp t1
LEFT JOIN
tmp t2
ON
t1.reservation_id = t2.reservation_id
LEFT JOIN
tmp t3
ON
t2.reservation_id = t3.reservation_id
WHERE
t1.ticket_type = 'ADULT'
AND
t2.ticket_type = 'CHILD'
AND
t3.ticket_type = 'INFANT';
...每个预订的一行显示三种故障单类型中的每一种的数量。
+----------------+------------+--------------+-------------+
| reservation_id | num_adults | num_children | num_infants |
+----------------+------------+--------------+-------------+
| 1 | 2 | 2 | 0 |
| 2 | 1 | 0 | 0 |
| 3 | 1 | 0 | 0 |
+----------------+------------+--------------+-------------+
我希望这是足够的信息。如果不是,请发表评论。
答案 0 :(得分:1)
如果你想坚持你的第一个查询,你可以将其分为第二个:
SELECT reservation_id,
SUM(CASE WHEN ticket_type='ADULT' THEN qty ELSE 0 END) AS adults,
SUM(CASE WHEN ticket_type='CHILD' THEN qty ELSE 0 END) AS children,
SUM(CASE WHEN ticket_type='INFANT' THEN qty ELSE 0 END) AS infants,
FROM tmp
GROUP BY reservation_id;
但是,我想知道你的架构。您正在存储qty
,即计算值。您是否考虑过为每个故障单实例添加一行。如果你这样做,那么就不需要tmp表,尽管你可以像上面那样进行数据透视。
答案 1 :(得分:1)
如果您的查询仅考虑以下3种类型:ADULT,CHILD,INFANT;您不必使用table ticket_type。
SELECT
r.reservation_id,
COALESCE(rd_adult.quantity,0) AS num_adults,
COALESCE(rd_child.quantity,0) AS num_children,
COALESCE(rd_infant.quantity,0) AS num_infants
FROM
reservation r
LEFT JOIN
reservation_detail rd_adult
ON r.reservation_id = rd_adult.reservation_id
and rd_adult.ticket_type = 'ADULT'
LEFT JOIN
reservation_detail rd_child
ON r.reservation_id = rd_child.reservation_id
and rd_child.ticket_type = 'CHILD'
LEFT JOIN
reservation_detail rd_infant
ON r.reservation_id = rd_infant.reservation_id
and rd_infant.ticket_type = 'INFANT'
答案 2 :(得分:1)
由于表reservation_detail包含您需要的所有字段,因此您无需连接其他表并创建临时表。
试试这个:
SELECT distinct
t.reservation_id,
COALESCE(t1.qty,0) AS num_adults,
COALESCE(t2.qty,0) AS num_children,
COALESCE(t3.qty,0) AS num_infants
FROM reservation t
LEFT JOIN reservation_detail t1 ON t.reservation_id = t1.reservation_id AND t1.ticket_type = 'ADULT'
LEFT JOIN reservation_detail t2 ON t.reservation_id = t2.reservation_id AND t2.ticket_type = 'CHILD'
LEFT JOIN reservation_detail t3 ON t.reservation_id = t3.reservation_id AND t3.ticket_type = 'INFANT';
答案 3 :(得分:0)
一个简单的GROUP BY就可以了:
SELECT t.reservation_id,
SUM(CASE
WHEN ticket_type = 'ADULT' THEN
COALESCE(rd.quantity, 0)
ELSE
0
END) num_adults,
SUM(CASE
WHEN ticket_type = 'CHILD' THEN
COALESCE(rd.quantity, 0)
ELSE
0
END) num_children,
SUM(CASE
WHEN ticket_type = 'INFANT' THEN
COALESCE(rd.quantity, 0)
ELSE
0
END) num_infants
FROM (SELECT * FROM (ticket_type tt, reservation r)) t
LEFT JOIN reservation_detail rd ON t.reservation_id = rd.reservation_id
AND t.ticket_type = rd.ticket_type
GROUP BY t.reservation_id