【问题标题】:How do inner join on Presto/AWS Athena?如何在 Presto/AWS Athena 上进行内部连接?
【发布时间】:2018-09-06 10:08:25
【问题描述】:

我正在尝试执行查询以选择在另一个表中的开始列和结束列定义的范围内的所有行。例如,使用伪代码,如果我有这些(非常小的)表:

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

我想做一个查询,返回如下内容:

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 子句,一个用于范围表的每一行(例如 BETWEEN 1 AND 5 OR BETWEEN 7 and 23 OR BETWEEN 2 AND 7 或 25 到 29 之间)。

似乎 BETWEEN 运算符在 presto 中的行为有所不同,因此相同的查询不会返回任何结果。

实际上,我的范围表有大约 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

【问题讨论】:

  • 我很乐意提供帮助,但要了解您的表格数据和要求并不容易。如果可能,请编辑您的问题并在输入表中显示一些行,以便我们可以尝试自己运行查询来测试您的场景。您也可以使用SQL Fiddle 创建示例数据集。
  • 谢谢,@JohnRotenstein - 这是一个有用的网站!

标签: sql amazon-web-services presto amazon-athena


【解决方案1】:

以下内容对我有用。我不得不解决 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;

rangespositions 目录包含 CSV 文件:

a,2,5
b,7,23
c,2,7
d,25,29

2,adfkjdas
3,sdlfkjaslkdfj
5,wwlekrj
9,sdlfkdj
27,zxcvzx

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-08
  • 2018-12-20
  • 1970-01-01
  • 2021-05-09
  • 2017-05-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多