简体   繁体   English

如何在SQL中每列值仅选择一行?

[英]How to select only one row per column value in SQL?

So, I have the following schema build_tasks: 因此,我具有以下架构build_tasks:

id|building|queue_time|start_time|completion_time|status|createdAt|updatedAt|baseId|

I'm trying to get only the build tasks that have status 'pending', where theres no build_task with the same baseId in status 'in-progress'. 我正在尝试仅获取状态为“待决”的构建任务,其中状态为“进行中”的build_task没有具有相同baseId的任务。

So far, I managed to get a table with all the pending build tasks where there's no in-progress build task. 到目前为止,我设法获得了一个表格,其中包含所有正在进行的构建任务,而没有正在进行的构建任务。 This is the query: 这是查询:

select * from (select build_tasks.* from build_tasks
            where status = 'pending') as p
left join in_progress_build_tasks ipbt on p."baseId" = ipbt."baseId"
      where ipbt."baseId" is null;

where in_progress_build_tasks is the view: 其中in_progress_build_tasks是视图:

CREATE OR REPLACE VIEW "public".in_progress_build_tasks AS
 SELECT DISTINCT build_tasks."baseId"
   FROM build_tasks
  WHERE build_tasks.status = 'in-progress'::enum_build_tasks_status;

Which for the table: 用于哪个表:

id |building            |queue_time          |start_time          |completion_time     |status      |createdAt           |updatedAt           |baseId |
---|--------------------|--------------------|--------------------|--------------------|------------|--------------------|--------------------|-------|
7  |resource01_refinery |2018-02-04 14:09:49 |                    |                    |pending     |2018-02-04 14:09:49 |2018-02-04 14:09:49 |1      |
10 |resource01_refinery |2018-02-04 14:45:07 |                    |                    |pending     |2018-02-04 14:45:07 |2018-02-04 14:45:07 |1      |
6  |resource01_refinery |2018-02-04 14:07:32 |2018-02-04 14:07:58 |2018-02-04 14:08:08 |in-progress |2018-02-04 14:07:32 |2018-02-04 14:08:09 |1      |
12 |resource01_refinery |2018-02-04 14:46:04 |2018-02-04 14:46:04 |2018-02-04 14:46:04 |successful  |2018-02-04 14:46:04 |2018-02-04 14:58:28 |2      |
8  |resource01_refinery |2018-02-04 14:10:29 |2018-02-04 14:10:29 |2018-02-04 14:10:39 |successful  |2018-02-04 14:10:29 |2018-02-04 14:10:39 |2      |
9  |resource01_refinery |2018-02-04 14:11:38 |                    |                    |pending     |2018-02-04 14:11:38 |2018-02-04 14:11:38 |2      |
11 |resource01_refinery |2018-02-04 14:45:14 |                    |                    |pending     |2018-02-04 14:45:14 |2018-02-04 14:45:14 |2      |
13 |resource01_refinery |2018-02-04 15:11:16 |                    |                    |pending     |2018-02-04 15:11:16 |2018-02-04 15:11:16 |3      |
15 |resource01_refinery |2018-02-04 15:11:19 |                    |                    |pending     |2018-02-04 15:11:19 |2018-02-04 15:11:19 |3      |
14 |resource01_refinery |2018-02-04 15:11:18 |                    |                    |pending     |2018-02-04 15:11:18 |2018-02-04 15:11:18 |3      |

Gives me the output: 给我输出:

id |building            |queue_time          |start_time |completion_time |status  |createdAt           |updatedAt           |baseId |baseId |
---|--------------------|--------------------|-----------|----------------|--------|--------------------|--------------------|-------|-------|
9  |resource01_refinery |2018-02-04 14:11:38 |           |                |pending |2018-02-04 14:11:38 |2018-02-04 14:11:38 |2      |       |
11 |resource01_refinery |2018-02-04 14:45:14 |           |                |pending |2018-02-04 14:45:14 |2018-02-04 14:45:14 |2      |       |
13 |resource01_refinery |2018-02-04 15:11:16 |           |                |pending |2018-02-04 15:11:16 |2018-02-04 15:11:16 |3      |       |
14 |resource01_refinery |2018-02-04 15:11:18 |           |                |pending |2018-02-04 15:11:18 |2018-02-04 15:11:18 |3      |       |
15 |resource01_refinery |2018-02-04 15:11:19 |           |                |pending |2018-02-04 15:11:19 |2018-02-04 15:11:19 |3      |       |

How can I reduce the results to only 1 row per base_id, selected based on the lowest queue_time? 如何将结果减少为每个base_id仅根据最低queue_time选择的行?

I am unclear what you want for output. 我不清楚您要输出什么。 But if you want to identify the base ids that meet your conditions, you can use aggregation: 但是,如果要确定满足条件的基本标识,则可以使用聚合:

select bt.baseid
from build_tasks bt
group by bt.baseid
having sum( (bt.status = 'pending'::enum_build_tasks_status)::int) > 0 and
       sum( (bt.status = 'in-progress'::enum_build_tasks_status)::int) = 0 ;

I am not sure what else you want in the output. 我不确定输出中还想要什么。 Likely you can get what you want using aggregation. 使用聚合可以得到想要的东西。 Alternatively, a join , in , or exists can get what you want. 另外, joininexists可以得到您想要的。

However, you do not a need a view to accomplish what you are doing. 但是,您不需要查看即可完成自己的工作。

You may apply DISTINCT ON (baseId) above your output. 您可以在输出上方应用DISTINCT ON (baseId)

SELECT * FROM
(

SELECT DISTINCT ON (baseId)  youroutput.*
  FROM youroutput ORDER BY baseId,updatedAt
) as a;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM