Hive - 通过聚合跨组的值来创建映射列类型

2024-04-22

我有一个看起来像这样的表:

|customer|category|room|date|
-----------------------------
|1       |   A    | aa | d1 |
|1       |   A    | bb | d2 |
|1       |   B    | cc | d3 |
|1       |   C    | aa | d1 |
|1       |   C    | bb | d2 |
|2       |   A    | aa | d3 |
|2       |   A    | bb | d4 |
|2       |   C    | bb | d4 |
|2       |   C    | ee | d5 |
|3       |   D    | ee | d6 |

我想从表中创建两个地图:

1st. 地图客户房间日期: will group by客户和collect所有不同的房间(key) 和日期 (value).

我正在使用collect() UDF布里克豪斯 https://github.com/klout/brickhouse功能。

这可以用类似的东西存档:

select customer, collect(room,date) as map_customer_room_date
from table
group by customer

2nd. 地图类别房间日期有点复杂,也由相同的地图类型组成collect(room, date)它将包含所有类别的所有房间作为键,其中客户 X 是类别。 这意味着对于客户1它会占用空间ee尽管它属于客户2。这是因为 customer1 有类别C并且此类别也存在于客户 2 中。

The 决赛桌按客户分组,如下所示:

|customer| map_customer_room_date  |     map_category_room_date    |
-------------------------------------------------------------------|
|   1    |{aa: d1, bb: d2, cc: d3} |{aa: d1, bb: d2, cc: d3,ee: d6}|
|   2    |{aa: d3, bb: d4, ee: d6} |{aa: d3, bb: d4, ee: d6}       |
|   3    |{ee: d6}                 |{ee: d6}                       |  

我在构建第二张地图并按所述呈现最终表格时遇到问题。 知道如何实现这一点吗?


这可以通过使用一系列自连接来找到同一类别中的其他房间,然后将结果合并到 2 个地图中来完成。

Code

CREATE TABLE `table` AS
SELECT 1 AS customer, 'A' AS category, 'aa' AS room, 'd1' AS `date` UNION ALL
SELECT 1 AS customer, 'A' AS category, 'bb' AS room, 'd2' AS `date` UNION ALL
SELECT 1 AS customer, 'B' AS category, 'cc' AS room, 'd3' AS `date` UNION ALL
SELECT 1 AS customer, 'C' AS category, 'aa' AS room, 'd1' AS `date` UNION ALL
SELECT 1 AS customer, 'C' AS category, 'bb' AS room, 'd2' AS `date` UNION ALL
SELECT 2 AS customer, 'A' AS category, 'aa' AS room, 'd3' AS `date` UNION ALL
SELECT 2 AS customer, 'A' AS category, 'bb' AS room, 'd4' AS `date` UNION ALL
SELECT 2 AS customer, 'C' AS category, 'bb' AS room, 'd4' AS `date` UNION ALL
SELECT 2 AS customer, 'C' AS category, 'ee' AS room, 'd5' AS `date` UNION ALL
SELECT 3 AS customer, 'D' AS category, 'ee' AS room, 'd6' AS `date`
;


SELECT
    customer_rooms.customer,
    collect(customer_rooms.room, customer_rooms.date) AS map_customer_room_date,
    collect(
        COALESCE(customer_category_rooms.room, category_rooms.room),
        COALESCE(customer_category_rooms.date, category_rooms.date)) AS map_category_room_date
FROM `table` AS customer_rooms
JOIN `table` AS category_rooms ON customer_rooms.category = category_rooms.category
LEFT OUTER JOIN `table` AS customer_category_rooms ON customer_rooms.customer = customer_category_rooms.customer
AND category_rooms.category = customer_category_rooms.category
AND category_rooms.room = customer_category_rooms.room
WHERE (
    customer_rooms.customer = customer_category_rooms.customer AND
    customer_rooms.category = customer_category_rooms.category AND
    customer_rooms.room = customer_category_rooms.room AND
    customer_rooms.date = customer_category_rooms.date
)
OR (
    customer_category_rooms.customer IS NULL AND
    customer_category_rooms.category IS NULL AND
    customer_category_rooms.room IS NULL AND
    customer_category_rooms.date IS NULL
)
GROUP BY
    customer_rooms.customer
;

结果集

1   {"aa":"d1","bb":"d2","cc":"d3"} {"aa":"d1","bb":"d2","cc":"d3","ee":"d5"}
2   {"aa":"d3","bb":"d4","ee":"d5"} {"aa":"d3","bb":"d4","ee":"d5"}
3   {"ee":"d6"} {"ee":"d6"}

解释

FROM `table` AS customer_rooms

首先,从初始结果中得出结果table。我们将这种关系命名为customer_rooms。正如您在问题中已经指出的那样,这足以构建map_customer_room_date.

JOIN `table` AS category_rooms ON customer_rooms.category = category_rooms.category

第一个自连接标识了与 中明确提到的房间具有相同类别的所有房间。customer_rooms行。我们将这种关系命名为category_rooms.

LEFT OUTER JOIN `table` AS customer_category_rooms ON customer_rooms.customer = customer_category_rooms.customer
AND category_rooms.category = customer_category_rooms.category
AND category_rooms.room = customer_category_rooms.room

第二次自连接采用我们在其中识别的房间category_rooms并尝试查找该房间是否已被中指定的客户占用customer_rooms。我们将这种关系命名为customer_category_rooms。这是一个LEFT OUTER JOIN,因为我们想要保留先前连接中的所有行。结果将是 1) 的值customer_rooms and customer_category_rooms是相同的,因为客户已经拥有这个房间,或者 2) 来自的值customer_category_rooms将是全部NULL,因为客户并不持有这个房间,但它是同一类别之一的房间。这种区别将变得很重要,以便我们能够保留date客户的信息(如果他们已经预订了房间)。

接下来,我们需要进行过滤。

WHERE (
    customer_rooms.customer = customer_category_rooms.customer AND
    customer_rooms.category = customer_category_rooms.category AND
    customer_rooms.room = customer_category_rooms.room AND
    customer_rooms.date = customer_category_rooms.date
)

这包括原始客户明确持有的房间table.

OR (
    customer_category_rooms.customer IS NULL AND
    customer_category_rooms.category IS NULL AND
    customer_category_rooms.room IS NULL AND
    customer_category_rooms.date IS NULL
)

这包括非客户持有但与客户持有的房间属于同一类别的房间。

    collect(customer_rooms.room, customer_rooms.date) AS map_customer_room_date,

map_customer_room_date可以通过从表中收集原始数据来构建,我们将其别名为customer_rooms.

    collect(
        COALESCE(customer_category_rooms.room, category_rooms.room),
        COALESCE(customer_category_rooms.date, category_rooms.date)) AS map_category_room_date

建筑map_category_room_date更复杂。如果客户明确保留房间,那么我们希望保留该房间date。但是,如果客户没有明确保留房间,那么我们希望能够使用room and date来自具有重叠类别的另一行。为了实现这一点,我们使用 HiveCOALESCE https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF#LanguageManualUDF-ConditionalFunctions函数选择第一个不是的值NULL。如果客户已经保留房间(如非NULL值在customer_category_rooms),然后我们将使用它。如果没有,那么我们将使用来自category_rooms反而。

请注意,如果相同的类别/房间组合可以映射到多个,则仍然可能存在一些歧义。date价值观。如果这很重要,那么您可能需要投入更多的工作来选择正确的date基于一些业务规则(例如使用最快的date) 或映射到多个date值而不是单个值。如果有类似的额外要求,这应该为您提供一个良好的起点。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hive - 通过聚合跨组的值来创建映射列类型 的相关文章

  • hadoop2.2.0追加文件发生AlreadyBeingCreatedException

    我遇到了一个关于hadoop2 2 0追加操作的问题 我通过 HDFS java API 将一些字节附加到 hdfs 文件 首先 如果在附加操作之前文件不存在 我将创建目标文件 代码如下 String fileUri hdfs hadoop
  • 是否值得购买 Mahout in Action 以跟上 Mahout 的速度,或者还有其他更好的来源吗?

    我目前是一个非常随意的用户阿帕奇马胡特 http mahout apache org 我正在考虑购买这本书象夫在行动 http www manning com owen 不幸的是 我很难理解这本书的价值 并且认为它是一本曼宁早期访问计划 h
  • Hadoop安装问题:

    我跟着this http www bogotobogo com Hadoop BigData hadoop Install on ubuntu single node cluster phpHadoop 安装教程 不幸的是 当我运行全部启动
  • 使用准备好的语句设置表名称

    我正在尝试使用准备好的语句来设置表名以从中选择数据 但在执行查询时不断收到错误 错误和示例代码如下所示 Microsoft ODBC Microsoft Access Driver Parameter Pa RaM000 specified
  • SSIS ODBC SQL 参数

    我在 odbc 源数据流任务中有一个 SQL 命令需要采用参数 但不存在添加参数的选项 我尝试将数据库添加为与 ODBC 提供程序的 ADO NET 连接 但也没有可用的参数 还尝试将其作为 OLEDB 连接 但没有可用于 ODBC 的提供
  • Oracle 中的 TO_Char 数字格式模型

    我不完全理解如何使用 to char 函数将数字转换为具有适当格式模型的字符串 实际数字具有以下格式 使用逗号作为小数点分隔符 始终为 5 个小数 整数最多可达 6 可能是无限的 但目前绝不会超过 6 数字可以是正数或负数 数字可以以 0
  • 从有序结果集中查找“运行”行

    我试图找出一种方法来识别满足某些条件的 运行 结果 按顺序连续行 目前 我正在订购结果集 并通过眼睛扫描特定模式 这是一个例子 SELECT the date name FROM orders WHERE the date BETWEEN
  • MYSQL中如何获取不带小数的列值

    我的 mysql 表中有两列A and B我正在获取这样的记录 select A B from table 但问题是上面的查询提供了类似这样的值 12 00 3 4 78 9 但我想得到这样的结果 12 3 78 我将使用哪个 MySQL
  • 为什么 Redshift 不需要物化视图或索引?

    In the 红移常见问题解答 https aws amazon com redshift faqs under 问 与大多数用于数据仓储和分析的传统数据库相比 Amazon Redshift 的性能如何 它说如下 高级压缩 列式数据存储比
  • 如何对 MySQL 数据库中的 ENUM 列进行排序?

    I have colorMySQL 表中的列类型为ENUM RED YELLOW MY COLOR BLACK 还有另一个name列的类型是VARCHAR 30 我想按以下顺序获取所有表行 YELLOW首先行 排序依据name RED最后一
  • SQL Server 选择具有最近日期时间的记录

    我有一张表如下 MyJob MyKey MyCode MyDate MyTime q183b 0131081a 24 100315 9 37 q183b 0131081a 9 100315 11 38 q183b 0132426a 1 90
  • 是否可以使用不在 GROUP BY 中的 ORDER BY 列?

    正如标题所说 这是我的代码 SELECT material SUM Amount AS Amount RIGHT CONVERT varchar 50 date in 106 8 FROM rec stats GROUP BY materi
  • HIVE 执行错误,从 org.apache.hadoop.hive.ql.exec.DDLTask 返回代码 1

    我在创建配置单元数据库时收到以下错误 FAILED 执行错误 从 org apache hadoop hive ql exec DDLTask 返回代码 1 com facebook fb303 FacebookService Iface
  • mysql中相同字符集和排序规则的varchar和nvarchar有什么区别

    谁能告诉我具有相同字符集和整理的 varchar 和 nvarchar 之间有什么区别 例子 varchar CHARACTER SET utf8mb4 COLLATE utf8mb4 unicode ci and nvarchar CHA
  • hive查询无法通过jdbc生成结果集

    我是 Hive 和 Hadoop 的新手 在我的教程中 我想将表创建为 import java sql SQLException import java sql Connection import java sql ResultSet im
  • 返回动态列集

    我创建了以下函数来根据该函数的参数返回列集 CREATE OR REPLACE FUNCTION getColumns IN column1 text IN column2 text IN column3 text IN column4 t
  • 为什么我的层次结构查询显示重复记录?

    我的要求是找到一个月中所有过去的天数 以下是我的示例查询 CREATE TABLE custom date full sno NUMBER curr date DATE INSERT INTO custom date full VALUES
  • MYSQL插入GB大小的巨大SQL文件

    我正在尝试创建 Wikipedia DB 副本 大约 50GB 但在处理最大的 SQL 文件时遇到问题 我使用 linux split 实用程序将 GB 大小的文件拆分为 300 MB 的块 例如 split d l 50 enwiki 2
  • SQL Server 2000 - 将查询分成 15 分钟的块

    我有一个连续时间数据集 我想使用 sql 将其分成 15 分钟的块 如果我能帮忙的话 我不想必须创建一个新表才能做到这一点 i e 时间 计数09 15 109 30 309 45 010 00 210 15 3 有谁知道我该怎么做 我认为
  • 将文件存储在文件系统上或在 SQL Server 中存储为 varbinary(MAX)

    我知道 对于将文件作为 blob 存储在数据库中是否是不好的做法存在很多争议 但我只是想了解这对于我的情况是否有意义 我正在创建一个 ASP NET 应用程序 在一家大公司内部使用 用户需要能够将文件附加到系统中的 作业 这些文件通常是 P

随机推荐