Reputation: 3267
I am wondering if there is any way to select two columns based on the outcome of an if statement.
Here is what I have so far ( I have cut off half of the unnecessary stuff ):
( SELECT IF(
(SELECT g.id
FROM users AS u
INNER JOIN user_groups AS g ON (g.id = u.group_id)
WHERE u.id = 2) >= 4,
(SELECT p.action, p.id
FROM permissions AS p
WHERE p.required_points <=
(SELECT reputation
FROM users
WHERE id = 2)),
(SELECT 0, 0)))
Basically, is there any multiple column operand that behave like if statements? and if so how would I implement them. Any links to resources will be greatly appreciate.
The error is:
#1241 - Operand should contain 1 column(s)
The entire sql query:
(SELECT p1.action,
p1.id
FROM user_permissions AS u1
INNER JOIN permissions AS p1 ON (p1.id = u1.action_id)
WHERE u1.user_id = 2)
UNION
(SELECT p2.action,
p2.id
FROM users AS u2
INNER JOIN user_groups AS g ON (g.id = u2.group_id)
INNER JOIN group_permissions AS gp ON (gp.group_id = g.id)
INNER JOIN permissions AS p2 ON (p2.id = gp.action_id)
WHERE u2.id = 2)
UNION
( SELECT IF(
(SELECT g2.id
FROM users AS u3
INNER JOIN user_groups AS g2 ON (g2.id = u3.group_id)
WHERE u3.id = 2) >= 4,
(SELECT p3.action, p3.id
FROM permissions AS p3
WHERE p3.required_points <=
(SELECT reputation
FROM users
WHERE id = 2)),
(SELECT 0, 0)))
Upvotes: 0
Views: 70
Reputation: 1269723
Oh, so that is basically the whole query. This won't work:
SELECT IF( (SELECT g2.id
FROM users u3 INNER JOIN
user_groups AS g2
ON g2.id = u3.group_id
WHERE u3.id = 2) >= 4,
(SELECT p3.action, p3.id
FROM permissions AS p3
WHERE p3.required_points <= (SELECT reputation FROM users WHERE id = 2)),
(SELECT 0, 0)))
So, just move the queries to a from
clause:
SELECT (case when g2.id >= 4, p3.action, 0),
(case when g2.id >= 4, p3.id, 0)
FROM (SELECT g2.id
FROM users u3 INNER JOIN
user_groups AS g2
ON g2.id = u3.group_id
WHERE u3.id = 2
) g2 cross join
(SELECT p3.action, p3.id
FROM permissions AS p3
WHERE p3.required_points <= (SELECT reputation FROM users WHERE id = 2))
) p3
If you don't really want the row with (0, 0)
, but it is there just so there is some other value, then let join
or where
filter it out:
SELECT p3.action, p3.id
FROM (SELECT p3.action, p3.id
FROM permissions AS p3
WHERE p3.required_points <= (SELECT reputation FROM users WHERE id = 2))
) p3
WHERE (SELECT g2.id
FROM users u3 INNER JOIN
user_groups AS g2
ON g2.id = u3.group_id
WHERE u3.id = 2
) >= 4
Upvotes: 1