SQL。如何从 table 获取唯一值但仅限于 1 列?
SQL. How to obtain unique values from table but only for 1 column?
我有一个 table1。我按名称和时间列对 table 进行排序:
SELECT name, value
FROM table1
WHERE time >= '2022-05-23 00:00:00' AND time <= '2022-05-23 01:00:00'
ORDER BY name, time
下一个我得到的结果 table :
name, value, time
A, 5, 2022-05-23 01:01:12
A, 9, 2022-05-23 01:02:11
A, 7, 2022-05-23 01:03:21
B, 5, 2022-05-23 01:04:23
B, 6, 2022-05-23 01:05:33
C, 7, 2022-05-23 01:06:30
C, 8, 2022-05-23 01:07:41
C, 3, 2022-05-23 01:08:44
C, 7, 2022-05-23 01:09:50
然后我需要 select 所有具有最短时间的唯一名称,并获得这些名称的值:
结果应该是这样的:
name, value, time
A, 5, 2022-05-23 01:01:12
B, 5, 2022-05-23 01:04:23
C, 7, 2022-05-23 01:06:30
============================================= ========================
事实证明,我们只是从 table:
中获取了每个第一个唯一名称
name, value, time
A, 5, 2022-05-23 01:01:12 <- take this one
A, 9, 2022-05-23 01:02:11
A, 7, 2022-05-23 01:03:21
B, 5, 2022-05-23 01:04:23 <- take this one
B, 6, 2022-05-23 01:05:33
C, 7, 2022-05-23 01:06:30 <- take this one
C, 8, 2022-05-23 01:07:41
C, 3, 2022-05-23 01:08:44
C, 7, 2022-05-23 01:09:50
我的目标是使用时间戳最少的唯一名称(或 table 中的每个第一个唯一名称,因为它已经按时间戳排序)
我不清楚如何获得想要的结果。
我尝试使用“SELECT DISTINCT 名称,值”,但它返回所有唯一名称和唯一值,但我只需要唯一名称+值(时间最短的地方)
一般你会使用ROW_NUMBER
,但是Clickhouse不支持解析函数。我们可以改用连接方法:
SELECT t1.*
FROM table1 t1
INNER JOIN
(
SELECT name, MIN(time) AS min_time
FROM table1
WHERE time >= '2022-05-23 00:00:00' AND time <= '2022-05-23 01:00:00'
GROUP BY name
) t2
ON t2.name = t1.name AND
t2.min_time = t1.time
WHERE
time >= '2022-05-23 00:00:00' AND time <= '2022-05-23 01:00:00';
可以使用函数argMin
聚合函数(https://clickhouse.com/docs/en/sql-reference/aggregate-functions/reference/argmin/) to achieve the desired result. If you need to get the latest row, there is the argMax
aggregation function (https://clickhouse.com/docs/en/sql-reference/aggregate-functions/reference/argmax/)。
argMin/argMax
的想法是 return 给定值的最小值或最大值的参数(time
,在您的用例中)。
示例数据:
select * from table1;
SELECT *
FROM table1
┌─name─┬─value─┬────────────────time─┐
│ A │ 5 │ 2022-05-23 01:01:12 │
│ A │ 5 │ 2022-05-23 01:01:12 │
│ A │ 5 │ 2022-05-23 01:01:12 │
│ A │ 5 │ 2022-05-23 01:01:12 │
│ A │ 9 │ 2022-05-23 01:02:11 │
│ A │ 7 │ 2022-05-23 01:03:21 │
│ B │ 5 │ 2022-05-23 01:04:23 │
│ B │ 6 │ 2022-05-23 01:05:33 │
│ C │ 7 │ 2022-05-23 01:06:30 │
│ C │ 8 │ 2022-05-23 01:07:41 │
│ C │ 3 │ 2022-05-23 01:08:44 │
│ C │ 7 │ 2022-05-23 01:09:50 │
└──────┴───────┴─────────────────────┘
12 rows in set. Elapsed: 0.002 sec.
由于您需要整行(而 argMin/argMax
需要一个参数),因此需要将其转换为另一个结构(本例中为元组),然后投影回它们的名称。以下查询 returns 第一个(或参数为 val
表达式的最小值):
SELECT
tpl.1 AS name,
tpl.2 AS value,
tpl.3 AS time
FROM (
SELECT
argMin(tuple(*), time) as tpl
FROM
table1
GROUP BY name
)
ORDER BY name
┌─name─┬─value─┬────────────────time─┐
│ A │ 5 │ 2022-05-23 01:01:12 │
│ B │ 5 │ 2022-05-23 01:04:23 │
│ C │ 7 │ 2022-05-23 01:06:30 │
└──────┴───────┴─────────────────────┘
3 rows in set. Elapsed: 0.004 sec.
由于 argMax
以类似的方式工作,但要获取最新的(或 val
表达式的最大值的参数),这将为您提供最新的(最新的)name/value/time 行:
SELECT
tpl.1 AS name,
tpl.2 AS value,
tpl.3 AS time
FROM
(
SELECT argMax(tuple(*), time) AS tpl
FROM table1
GROUP BY name
)
ORDER BY name ASC
┌─name─┬─value─┬────────────────time─┐
│ A │ 7 │ 2022-05-23 01:03:21 │
│ B │ 6 │ 2022-05-23 01:05:33 │
│ C │ 7 │ 2022-05-23 01:09:50 │
└──────┴───────┴─────────────────────┘
3 rows in set. Elapsed: 0.002 sec.
我有一个 table1。我按名称和时间列对 table 进行排序:
SELECT name, value
FROM table1
WHERE time >= '2022-05-23 00:00:00' AND time <= '2022-05-23 01:00:00'
ORDER BY name, time
下一个我得到的结果 table :
name, value, time
A, 5, 2022-05-23 01:01:12
A, 9, 2022-05-23 01:02:11
A, 7, 2022-05-23 01:03:21
B, 5, 2022-05-23 01:04:23
B, 6, 2022-05-23 01:05:33
C, 7, 2022-05-23 01:06:30
C, 8, 2022-05-23 01:07:41
C, 3, 2022-05-23 01:08:44
C, 7, 2022-05-23 01:09:50
然后我需要 select 所有具有最短时间的唯一名称,并获得这些名称的值:
结果应该是这样的:
name, value, time
A, 5, 2022-05-23 01:01:12
B, 5, 2022-05-23 01:04:23
C, 7, 2022-05-23 01:06:30
============================================= ========================
事实证明,我们只是从 table:
中获取了每个第一个唯一名称name, value, time
A, 5, 2022-05-23 01:01:12 <- take this one
A, 9, 2022-05-23 01:02:11
A, 7, 2022-05-23 01:03:21
B, 5, 2022-05-23 01:04:23 <- take this one
B, 6, 2022-05-23 01:05:33
C, 7, 2022-05-23 01:06:30 <- take this one
C, 8, 2022-05-23 01:07:41
C, 3, 2022-05-23 01:08:44
C, 7, 2022-05-23 01:09:50
我的目标是使用时间戳最少的唯一名称(或 table 中的每个第一个唯一名称,因为它已经按时间戳排序)
我不清楚如何获得想要的结果。 我尝试使用“SELECT DISTINCT 名称,值”,但它返回所有唯一名称和唯一值,但我只需要唯一名称+值(时间最短的地方)
一般你会使用ROW_NUMBER
,但是Clickhouse不支持解析函数。我们可以改用连接方法:
SELECT t1.*
FROM table1 t1
INNER JOIN
(
SELECT name, MIN(time) AS min_time
FROM table1
WHERE time >= '2022-05-23 00:00:00' AND time <= '2022-05-23 01:00:00'
GROUP BY name
) t2
ON t2.name = t1.name AND
t2.min_time = t1.time
WHERE
time >= '2022-05-23 00:00:00' AND time <= '2022-05-23 01:00:00';
可以使用函数argMin
聚合函数(https://clickhouse.com/docs/en/sql-reference/aggregate-functions/reference/argmin/) to achieve the desired result. If you need to get the latest row, there is the argMax
aggregation function (https://clickhouse.com/docs/en/sql-reference/aggregate-functions/reference/argmax/)。
argMin/argMax
的想法是 return 给定值的最小值或最大值的参数(time
,在您的用例中)。
示例数据:
select * from table1;
SELECT *
FROM table1
┌─name─┬─value─┬────────────────time─┐
│ A │ 5 │ 2022-05-23 01:01:12 │
│ A │ 5 │ 2022-05-23 01:01:12 │
│ A │ 5 │ 2022-05-23 01:01:12 │
│ A │ 5 │ 2022-05-23 01:01:12 │
│ A │ 9 │ 2022-05-23 01:02:11 │
│ A │ 7 │ 2022-05-23 01:03:21 │
│ B │ 5 │ 2022-05-23 01:04:23 │
│ B │ 6 │ 2022-05-23 01:05:33 │
│ C │ 7 │ 2022-05-23 01:06:30 │
│ C │ 8 │ 2022-05-23 01:07:41 │
│ C │ 3 │ 2022-05-23 01:08:44 │
│ C │ 7 │ 2022-05-23 01:09:50 │
└──────┴───────┴─────────────────────┘
12 rows in set. Elapsed: 0.002 sec.
由于您需要整行(而 argMin/argMax
需要一个参数),因此需要将其转换为另一个结构(本例中为元组),然后投影回它们的名称。以下查询 returns 第一个(或参数为 val
表达式的最小值):
SELECT
tpl.1 AS name,
tpl.2 AS value,
tpl.3 AS time
FROM (
SELECT
argMin(tuple(*), time) as tpl
FROM
table1
GROUP BY name
)
ORDER BY name
┌─name─┬─value─┬────────────────time─┐
│ A │ 5 │ 2022-05-23 01:01:12 │
│ B │ 5 │ 2022-05-23 01:04:23 │
│ C │ 7 │ 2022-05-23 01:06:30 │
└──────┴───────┴─────────────────────┘
3 rows in set. Elapsed: 0.004 sec.
由于 argMax
以类似的方式工作,但要获取最新的(或 val
表达式的最大值的参数),这将为您提供最新的(最新的)name/value/time 行:
SELECT
tpl.1 AS name,
tpl.2 AS value,
tpl.3 AS time
FROM
(
SELECT argMax(tuple(*), time) AS tpl
FROM table1
GROUP BY name
)
ORDER BY name ASC
┌─name─┬─value─┬────────────────time─┐
│ A │ 7 │ 2022-05-23 01:03:21 │
│ B │ 6 │ 2022-05-23 01:05:33 │
│ C │ 7 │ 2022-05-23 01:09:50 │
└──────┴───────┴─────────────────────┘
3 rows in set. Elapsed: 0.002 sec.