【问题标题】:left join and group by左加入并分组
【发布时间】:2017-05-30 05:55:42
【问题描述】:

我有如下两个表,我想根据在任务表中使用的位置行列出,并且不要重复 location.id,也在任务表中按列排序。

我不确定如何使用 group by 或其他方法解决它?
(我之前也检查过 distinct,但它限制选择特定列,似乎不是我想要的..)
如何解决?

location
id | status | ...
1  | ...
2  | ...

id SERIAL NOT NULL

task
id | location_id | create_date | start_date | ...
1  | 1           | ...
2  | 1           | ...
3  | 2           | ...

id SERIAL NOT NULL
location_id integer DEFAULT NULL
create_date timestamp without time zone NOT NULL  
start_date date NOT NULL

需要输出结果

location  order by task.create_date
id | ...
1  | ...
2  | ...

查询

我添加了 select t.location_id 它可以计数,但我在选择行中仍然有问题

计算作品

SELECT count(l.*)
   AS total_row_count 
   FROM location l
         LEFT JOIN (
           SELECT t.location_id
           FROM task t
           GROUP BY t.location_id
           ) t ON t.location_id  = l.id
        WHERE l.status = ANY($1::int[])

选择

SELECT
  l.* 
  FROM location l 
        LEFT JOIN (
          SELECT t.location_id, t.create_date
          FROM task t
          GROUP BY t.location_id
          ) t ON t.location_id  = l.id
       WHERE l.status = ANY($1::int[]) 
       ORDER BY t.create_date desc NULLS LAST, 
       l.name asc NULLS LAST, l.id desc NULLS LAST OFFSET $2 LIMIT $3

错误:

列“t.create_date”必须出现在 GROUP BY 子句中或被使用 在聚合函数中 SELECT t.create_date, t.location_id

【问题讨论】:

  • 我不明白你想要得到什么结果。将其显示为表格,就像您对示例数据所做的那样。
  • 请看我的更新,我想获取位置表但不重复位置行
  • 您的样本数据不完整。您能否提供相关列中的数据?
  • @user1775888 样本输出可以通过select * from location获取。显然你没有提供一个实质性的例子。如果您需要帮助,您需要展示您正在努力实现的目标。

标签: sql postgresql group-by left-join


【解决方案1】:

你可以简单地做一个左连接来获取任务表中的 location_id 和相应的行数,如下所示:

select l.id, count(t.location_id) times
from location l
left join task t
on l.id = t.location_id
group by l.id
order by max(t.create_date) desc;

如果 location_id 在您的位置表中是唯一的(可能是 PK)并且您想从该表中选择所有或更多列,您可以将它们放在查询的 select 和 group by 子句中。

【讨论】:

  • 感谢回复,我的问题是如何获取行数? t.create 不是唯一的,如何在 group by 中使用?但我需要它按顺序使用
  • 由于您在 location_id 上进行聚合,因此您需要按日期的聚合进行排序(可能是我在更新答案中使用的最大值或最小值)。
  • 选择 l.location_id ??还是选择 l.id?按 l.location_id 分组??或 l.id 或 t.location_id ?
  • @user1775888 是的。 l.id。更新
  • 我尝试使用这种语法来做这样的计数 SELECT count(l.*) AS total_row_count FROM location l LEFT JOIN task t ON t.location_id = l.id WHERE l.status = ANY($1::int[]) GROUP BY l.id 但它会获取所有位置行,我错过了什么
【解决方案2】:

如果您只想列出表location的记录和列,则可以使用exists,如下所示:

select * from location l where exists (select 1 from task where location_id=l.id)

你可以找到一个演示here

【讨论】:

  • 感谢回复,但我也想按任务表中的列排序
  • 好吧,你从来没有在你的问题中提到任何关于订购的事情。那么,您希望如何 对数据进行排序?如果可能的话,您应该相应地编辑您的原始帖子。
  • 是的,但是当有多个t.create_date 时,您要使用哪个?第一个还是最后一个? @Gurv 在他的回答中假设后者。
  • 哦!我得到了它!我没有意识到这一点。最小或最大对我来说没问题,我想知道如何正确使用组
  • 是这样的正确语法,拳头 left join ,然后按 l.id 分组,然后按SELECT l.* FROM location l LEFT JOIN task t ON t.location_id = l.id WHERE l.status = ANY($1::int[]) GROUP BY l.id ORDER BY max(t.create_date) desc NULLS LAST, l.name asc NULLS LAST, l.id desc NULLS LAST OFFSET $2 LIMIT $3 的顺序使用 max 或 min
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-13
  • 2017-03-10
  • 2022-06-15
  • 2015-12-18
  • 2011-06-01
  • 2019-07-27
  • 1970-01-01
相关资源
最近更新 更多