如何在 Presto/AWS Athena 上进行 inner join?
How do inner join on Presto/AWS Athena?
我正在尝试对 select 属于另一个 table 中开始和结束列所定义范围内的所有行执行查询。例如,使用伪代码,如果我有这些(非常小)tables:
ranges:
group_id = c("a", "b", "c", "d"),
start = c(1, 7, 2, 25),
end = c(5, 23, 7, 29)
positions:
position = 100 random numbers
annotation = 100 random strings
我想查询 return 类似于:
group_id position annotation
a 2 adfkjdas
a 3 sdlfkjasl;kdfj
b 9 sdlfkdj
c 5 wwlekrj
d 27 zxcvzx
使用 MariaDB/MySQL,BETWEEN 查询将在范围内按行操作,因此这会起作用:
SELECT
ranges.group_id as group_id,
positions.position as position,
positions.annotation as annotation
FROM
(SELECT * FROM my_ranges) AS ranges, positions
WHERE
positions.position BETWEEN ranges.start AND ranges.end
也就是说,查询就像 WHERE 子句实际上是由 "OR" 连接的一系列 WHERE 子句一样,每个子句对应范围 table 的每一行(例如 BETWEEN 1 AND 5 OR 7 和 23 之间或 2 和 7 之间或 25 和 29 之间)。
似乎 BETWEEN 运算符在 presto 中的行为有所不同,因此相同的查询不会 return 任何结果。
实际上,我的范围 table 有大约 20,000 个范围我想查询,因此通过编写 OR 语句加入它们似乎令人望而却步...
这里有人可以建议修改此查询(或我的一般方法!)以使用 Presto 的方法吗?
(为回应评论而添加):对于比伪代码更多的 SQL,我想
use tables like this:
CREATE TABLE IF NOT EXISTS `ranges` (
`group_id` char,
`start` int(3),
`end` int(3)
);
INSERT INTO `ranges` (`group_id`, `start`, `end`) VALUES
('a', '2', '5'),
('b', '7', '23'),
('c', '2', '7'),
('d', '25', '29');
CREATE TABLE IF NOT EXISTS `positions` (
`position` int(3),
`annotation` varchar(20)
);
INSERT INTO `positions` (`position`, `annotation`) VALUES
('2', 'adfkjdas'),
('3', 'sdlfkjasl;kdfj'),
('5', 'wwlekrj'),
('9', 'sdlfkdj'),
('27', 'zxcvzx');
和 运行 这样的查询:
SELECT
group_id,
position,
annotation
FROM
ranges, positions
WHERE
positions.position BETWEEN ranges.start AND ranges.end
以下对我有用。我不得不解决 end
是保留字的事实:
CREATE EXTERNAL TABLE IF NOT EXISTS ranges (
group_id string,
start_value int,
end_value int
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
LOCATION 's3://my-bucket/ranges/';
CREATE EXTERNAL TABLE IF NOT EXISTS positions (
position int,
annotation string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
LOCATION 's3://my-bucket/positions/';
SELECT
group_id,
position,
annotation
FROM
ranges, positions
WHERE
positions.position BETWEEN ranges.start_value AND ranges.end_value;
ranges
和 positions
目录包含 CSV 文件:
a,2,5
b,7,23
c,2,7
d,25,29
和
2,adfkjdas
3,sdlfkjaslkdfj
5,wwlekrj
9,sdlfkdj
27,zxcvzx
我正在尝试对 select 属于另一个 table 中开始和结束列所定义范围内的所有行执行查询。例如,使用伪代码,如果我有这些(非常小)tables:
ranges:
group_id = c("a", "b", "c", "d"),
start = c(1, 7, 2, 25),
end = c(5, 23, 7, 29)
positions:
position = 100 random numbers
annotation = 100 random strings
我想查询 return 类似于:
group_id position annotation
a 2 adfkjdas
a 3 sdlfkjasl;kdfj
b 9 sdlfkdj
c 5 wwlekrj
d 27 zxcvzx
使用 MariaDB/MySQL,BETWEEN 查询将在范围内按行操作,因此这会起作用:
SELECT
ranges.group_id as group_id,
positions.position as position,
positions.annotation as annotation
FROM
(SELECT * FROM my_ranges) AS ranges, positions
WHERE
positions.position BETWEEN ranges.start AND ranges.end
也就是说,查询就像 WHERE 子句实际上是由 "OR" 连接的一系列 WHERE 子句一样,每个子句对应范围 table 的每一行(例如 BETWEEN 1 AND 5 OR 7 和 23 之间或 2 和 7 之间或 25 和 29 之间)。
似乎 BETWEEN 运算符在 presto 中的行为有所不同,因此相同的查询不会 return 任何结果。
实际上,我的范围 table 有大约 20,000 个范围我想查询,因此通过编写 OR 语句加入它们似乎令人望而却步...
这里有人可以建议修改此查询(或我的一般方法!)以使用 Presto 的方法吗?
(为回应评论而添加):对于比伪代码更多的 SQL,我想
use tables like this:
CREATE TABLE IF NOT EXISTS `ranges` (
`group_id` char,
`start` int(3),
`end` int(3)
);
INSERT INTO `ranges` (`group_id`, `start`, `end`) VALUES
('a', '2', '5'),
('b', '7', '23'),
('c', '2', '7'),
('d', '25', '29');
CREATE TABLE IF NOT EXISTS `positions` (
`position` int(3),
`annotation` varchar(20)
);
INSERT INTO `positions` (`position`, `annotation`) VALUES
('2', 'adfkjdas'),
('3', 'sdlfkjasl;kdfj'),
('5', 'wwlekrj'),
('9', 'sdlfkdj'),
('27', 'zxcvzx');
和 运行 这样的查询:
SELECT
group_id,
position,
annotation
FROM
ranges, positions
WHERE
positions.position BETWEEN ranges.start AND ranges.end
以下对我有用。我不得不解决 end
是保留字的事实:
CREATE EXTERNAL TABLE IF NOT EXISTS ranges (
group_id string,
start_value int,
end_value int
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
LOCATION 's3://my-bucket/ranges/';
CREATE EXTERNAL TABLE IF NOT EXISTS positions (
position int,
annotation string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
LOCATION 's3://my-bucket/positions/';
SELECT
group_id,
position,
annotation
FROM
ranges, positions
WHERE
positions.position BETWEEN ranges.start_value AND ranges.end_value;
ranges
和 positions
目录包含 CSV 文件:
a,2,5
b,7,23
c,2,7
d,25,29
和
2,adfkjdas
3,sdlfkjaslkdfj
5,wwlekrj
9,sdlfkdj
27,zxcvzx