我有两张表user_expenses
和users
。
user_expenses
的外键是user_expenses.user_id
,对应users.id
。
我想从两个表中获取一些信息,其中用户只有一笔费用。
我试了一下:
SELECT
users.id, users.email, users.stripe_plan, users.previous_plan,
users.created_at, user_expenses.created_at, user_expenses.description
FROM
users
INNER JOIN
user_expenses ON user_expenses.user_id = users.id
WHERE
user_expenses.description NOT LIKE "%free%"
GROUP BY
user_expenses.user_id
HAVING
COUNT(*) = 1
但是,当然,这会产生以下问题:
SELECT列表不在GROUP BY子句中,并且包含非聚合列&app; user.expenses.created_at'它在功能上不依赖于GROUP BY子句中的列;这与sql_mode = only_full_group_by
不兼容
将此列添加到group_by
是有问题的,因为它实际上会返回具有不同描述的多个费用的用户。
有人可以就如何解决这个问题提出一些建议吗?我只希望用户在user_expenses
表中只有一个条目,无论描述的类型如何。
答案 0 :(得分:1)
您可以进行虚拟聚合。变化:
user_expenses.created_at, user_expenses.description
在select
列表中:
min(user_expenses.created_at) created_at, min(user_expenses.description) description
...这与原始值相同,因为您知道每组只有一个。
通过users.id
字段进行分组也更为自然,因为它允许外部加入user_expenses
表(如果你需要的话):
group by users.id
注意:在MySql 5.7+中,没有必要聚合functionally dependent on the grouped-by fields的字段。由于users
记录的所有字段都由users.id
值确定,因此它们可以不进行聚合。
答案 1 :(得分:1)
您可以执行子查询,也可以伪聚合不在列表中的值:
(1):
SELECT users.id, users.email, users.stripe_plan, users.previous_plan, users.created_at, user_expenses.created_at, user_expenses.description
FROM users
INNER JOIN user_expenses
ON user_expenses.user_id = users.id
WHERE user_expenses.description NOT LIKE "%free%"
and users.id not in
(select ue2.user_id from user_expenses ue2 group by user_id having count(*) > 1)
(2)
SELECT users.id, max(users.email), max(users.stripe_plan), max(users.previous_plan), max(users.created_at), max(user_expenses.created_at), max(user_expenses.description)
FROM users
INNER JOIN user_expenses
ON user_expenses.user_id = users.id
WHERE user_expenses.description NOT LIKE "%free%"
GROUP BY user_expenses.user_id
HAVING COUNT(*) = 1