假设有一张表:

CREATE TABLE details(id String, detail_one UInt64, detail_two UInt64) ENGINE = Memory;
INSERT INTO TABLE details(id, detail_one, detail_two) VALUES ('id1', 5, 10), ('id2', 20, 30);

我希望能够将其"左联接"到输入值的外部数组,这样在从数据库获得结果集之后,就不必执行额外的基于散列映射的查找.这包括我在此输入数组上使用纯WHERE INUNIONtry 的解决方案.总的来说,这是个坏主意吗?你能推荐一个更好的 Select 吗?

大概是这样的:

SELECT *
FROM ['id1', 'id2', 'id3-missing'] AS input
LEFT JOIN details ON details.id = input;

因此结果集如下所示:

{
    ('id2', 5, 10), 
    ('id1', 20, 30),
    ('id3-missing', NULL, NULL) # basically return NULLs
}

备注:

  1. 这是一个相当小的表:少于10000行(主要是列),在这方面不会有太大变化,输入数组的大小可以进行类似的调整.
  2. 它必须支持额外的聚合,我将在其上执行这些聚合.

推荐答案

考虑使用arrayJoin函数:

SELECT *
FROM
(
    SELECT arrayJoin(['id1', 'id2', 'id3-missing']) AS id
) AS input
LEFT JOIN details ON details.id = input.id
SETTINGS join_use_nulls = 1

/*
┌─id──────────┬─details.id─┬─detail_one─┬─detail_two─┐
│ id1         │ id1        │          5 │         10 │
│ id2         │ id2        │         20 │         30 │
│ id3-missing │ ᴺᵁᴸᴸ       │       ᴺᵁᴸᴸ │       ᴺᵁᴸᴸ │
└─────────────┴────────────┴────────────┴────────────┘
*/

SELECT *
FROM details
RIGHT JOIN
(
    SELECT arrayJoin(['id1', 'id2', 'id3-missing']) AS id
) AS input ON details.id = input.id
SETTINGS join_use_nulls = 1

/*
┌─id──┬─detail_one─┬─detail_two─┬─input.id─┐
│ id1 │          5 │         10 │ id1      │
│ id2 │         20 │         30 │ id2      │
└─────┴────────────┴────────────┴──────────┘
┌─id───┬─detail_one─┬─detail_two─┬─input.id────┐
│ ᴺᵁᴸᴸ │       ᴺᵁᴸᴸ │       ᴺᵁᴸᴸ │ id3-missing │
└──────┴────────────┴────────────┴─────────────┘
*/

SELECT
    *,
    input.tuple.1 AS array_id,
    input.tuple.2 AS array_value
FROM
(
    SELECT arrayJoin([('id1', 100), ('id2', 200), ('id3-missing', 300)]) AS tuple
) AS input
LEFT JOIN details ON details.id = (input.tuple.1)

/*
┌─tuple───────────────┬─id──┬─detail_one─┬─detail_two─┬─array_id────┬─array_value─┐
│ ('id1',100)         │ id1 │          5 │         10 │ id1         │         100 │
│ ('id2',200)         │ id2 │         20 │         30 │ id2         │         200 │
│ ('id3-missing',300) │     │          0 │          0 │ id3-missing │         300 │
└─────────────────────┴─────┴────────────┴────────────┴─────────────┴─────────────┘
*/

Sql相关问答推荐

创建每小时重置的序列号

PG SQL中按条件聚合值

SUM(条件)在Oracle?

替换上一个或下一个值中的空值并添加其价格日期

从字符串中删除";1、";和";2,";,而不删除";11、";和";12、";

我需要一个regexp_like来只验证字母D或T、数字和管道

Oracle PL/SQL:解决DBMS输出大小限制的问题

SQL JSON_QUERY 使用列中的值构造 json 路径并接收错误

如何在android房间中进行多个加入

我需要在 ASP.NET C# 中获取 2 个 SQL 查询结果的平均值

如何根据共同列值从两个表中包含列,但只包含左表中的行

正则表达式:停在第一个匹配的其中一个字符位置上

SQL获取两个日期范围之间的计数

Postgresql 需要一个查询,为我提供所有没有具有特定状态值的子元素的父母

字符串从更改到表列和查询中的一行的转换错误

如何更改 duckdb R 中的数据约束

使用 SAVE TRANSACTION 时 BEGIN 和 COMMIT 语句的数量不匹配

SQL 计数和过滤查询优化

每组跨行曲折?

Amazon Redshift - 子计划的哈希表不存在