如何使用多个范围内的行数创建 select 查询

How to create a select query with count of rows that fall within multiple ranges

我正在尝试找到一种方法来创建新的 table 或 select 查询来计算落在多个预定义范围内的行数。我当前的限制是我无法使用引用带有类别的 table 的新列来更新任何 table。

我正在尝试使用属于某个类别的行数创建以下 table:

Id category_id category_name count
1 1 slow 3
2 2 medium 1
3 3 fast 2

下面是 table #1 和 #2 的架构:

Table#1:

Id category_name start_range end_range
1 slow 0 9
2 medium 10 19
3 fast 20 29

Table#2:

Id test_time
1 3
2 4
3 6
4 14
5 25
6 26

我需要循环每个类别并找到每个类别的计数。

以下查询无效:

SELECT *, (
    SELECT count(*) 
        FROM temp_times as tt
    WHERE tt.test_time > ttc.start_date AND
        tt.test_time <= ttc.end_date
    ) FROM temp_test_times_classification as ttc
;

下面的查询为我正在使用的模式构建临时 tables。

-- Table #1
CREATE TEMPORARY TABLE temp_test_times_classification(
   id SERIAL PRIMARY KEY, 
   category_name text,
   start_range int,
   end_range int
);

INSERT INTO 
    temp_test_times_classification (category_name, start_range, end_range)
VALUES
    ('slow', 0,10),
    ('medium', 10,20),
    ('fast', 20,30);


-- Table #2
CREATE TEMPORARY TABLE temp_times(
   id SERIAL PRIMARY KEY, 
   test_time int
);

INSERT INTO 
    temp_times (test_time)
VALUES
(3),
(4),
(6),
(14),
(25),
(26);


CREATE TEMPORARY TABLE expected_results_table(
   id SERIAL PRIMARY KEY, 
   test_times_classification_id INT,
   test_times_count INT
);

INSERT INTO 
    expected_results_table (test_times_classification_id, test_times_count)
VALUES
    (1, 3),
    (2, 1),
    (3, 2);


SELECT * FROM temp_test_times_classification;

SELECT * FROM temp_times;


-- Expected Results table
SELECT  tttct.category_name, ert.test_times_count FROM expected_results_table ert
    INNER JOIN temp_test_times_classification AS tttct
    ON tttct.id = ert.test_times_classification_id
    ;

一种方法是横向连接:

select *
from table1 t1 left join lateral
     (select count(*) as count
      from table2 t2
      where t2.teset_time between t1.start_range and t1.end_range
     ) t2
     on 1=1;

您也可以只使用 joingroup by:

select t1.Id, t1.category_id, t1.category_name,
       count(t2.id) as count
from table1 t1 left join
     table2 t2
     on t2.teset_time between t1.start_range and t1.end_range
group by t1.Id, t1.category_id, t1.category_name

请不要在没有告诉我们什么 不工作的情况下说“查询不工作”。事实上,您应该收到以下语法错误消息

ERROR:  column ttc.start_date does not exist
LINE 4:     WHERE tt.test_time > ttc.start_date AND
                                 ^
HINT:  Perhaps you meant to reference the column "ttc.start_range".

这确实说明了很多,不是吗?按照提示,更正查询中的列名,一切运行正常:

SELECT *, (
    SELECT count(*) 
        FROM temp_times as tt
    WHERE tt.test_time > ttc.start_range AND
        tt.test_time <= ttc.end_range
    ) FROM temp_test_times_classification as ttc
;

演示:https://dbfiddle.uk/?rdbms=postgres_13&fiddle=cfcde9e81d9ee5f8783d13bdf784d25b