代码之家  ›  专栏  ›  技术社区  ›  bheavner

如何在Presto/AWS Athena上进行内部连接?

  •  0
  • bheavner  · 技术社区  · 6 年前

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

    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子句,范围表的每一行一个WHERE子句(例如,介于1和5之间、介于7和23之间、介于2和7之间、介于25和29之间)。

    似乎BETWEEN操作符在presto中的行为不同,因此同一查询不会返回任何结果。

    在realty中,我的ranges表有大约20000个范围要查询,所以通过编写或语句来连接它们似乎是禁止的。。。

    这里有人能提出修改此查询的方法吗(或我的一般方法!)与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
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   John Rotenstein    6 年前

    以下内容对我有用。我不得不回避这样一个事实 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