我无法正确地对派生表的别名进行语法处理:
SELECT * FROM
(SELECT a.*, b.*
FROM a INNER JOIN b ON a.B_id = b.B_id
WHERE a.flag IS NULL AND b.date < NOW()
UNION
SELECT a.*, b.*
FROM a INNER JOIN b ON a.B_id = b.B_id
INNER JOIN c ON a.C_id = c.C_id
WHERE a.flag IS NOT NULL AND c.date < NOW())
AS t1
ORDER BY RAND() LIMIT 1
我收到了B_id的重复列名。有什么建议吗?
答案 0 :(得分:5)
问题不是union
,而是每个内部选择语句中的select a.*, b.*
- 因为a
和b
都有B_id
列,这意味着你在结果中有两个B_id
列。
您可以通过将选择更改为以下内容来解决此问题:
select a.*, b.col_1, b.col_2 -- repeat for columns of b you need
通常,我会避免在您从代码中使用的查询中使用select table1.*
(而不仅仅是交互式查询)。如果有人在表中添加了一列,则各种查询可能会突然停止工作。
答案 1 :(得分:3)
在派生表中,您正在检索表a和表b中存在的列ID,因此您需要选择其中一个或为它们提供别名:
SELECT * FROM
(SELECT a.*, b.[all columns except id]
FROM a INNER JOIN b ON a.B_id = b.B_id
WHERE a.flag IS NULL AND b.date < NOW()
UNION
SELECT a.*, b.[all columns except id]
FROM a INNER JOIN b ON a.B_id = b.B_id
INNER JOIN c ON a.C_id = c.C_id
WHERE a.flag IS NOT NULL AND c.date < NOW())
AS t1
ORDER BY RAND() LIMIT 1
答案 2 :(得分:1)
首先,您可以使用UNION ALL
代替UNION
。由于a.flag
上的排除条件,两个子查询将没有公共行。
你可以写的另一种方式是:
SELECT a.*, b.*
FROM a
INNER JOIN b
ON a.B_id = b.B_id
WHERE ( a.flag IS NULL
AND b.date < NOW()
)
OR
( a.flag IS NOT NULL
AND EXISTS
( SELECT *
FROM c
WHERE a.C_id = c.C_id
AND c.date < NOW()
)
)
ORDER BY RAND()
LIMIT 1