以下是TestingTable1中按日期降序排列的数据
BUYER_ID | ITEM_ID | CREATED_TIME
----------+-----------------+----------------------
1345653 110909316904 2012-07-09 21:29:06
1345653 151851771618 2012-07-09 19:57:33
1345653 221065796761 2012-07-09 19:31:48
1345653 400307563710 2012-07-09 18:57:33
如果这是TestingTable2中的以下数据,按日期降序排序
USER_ID | PRODUCT_ID | LAST_TIME
---------+----------------+-----------------------
1345653 110909316904 2012-07-09 22:29:06
1345653 150851771618 2012-07-09 19:57:33
TestingTable1
中的每一行都应与TestingTable2
匹配,如果不匹配或者TestingTable2中没有数据,那么我需要在输出中显示它们,如TestingTable1
我所知有这个数据,但对应TestingTable2
我有这个数据(这将是错误的数据),所以我可以看到什么是不匹配和缺少什么数据。
我需要在TestingTable2
和TestingTable1
上将BUYER_ID
与USER_ID
进行比较。我需要看一下,如果BUYER_ID
和USER_ID
匹配,那么我需要将ITEM_ID
与PRODUCT_ID
和CREATED_TIME
与LAST_TIME
进行比较,如果有的话与TestingTable2
中的任何一个或两者中的TestingTable1
进行比较后,TestingTable1
不匹配,那么我需要显示结果。
因此,如果你看一下上面的例子 - 基本上我有三个场景
ITEM_ID
中,第一行PRODUCT_ID
与TestingTable2
的第一行中的CREATED_TIME
匹配,但LAST_TIME
与TestingTable1
不匹配{1}}表示两个表中的第一行CREATED_TIME
中,第二行LAST_TIME
与TestingTable2
第二行中的ITEM_ID
匹配但PRODUCT_ID
与TestingTable1
不匹配{1}}表示两个表中的第二行TestingTable2
中,TestingTable2
中的最后两行(行)根本不存在。我编写的查询中未涉及此方案。我也希望在我的查询中使用此方案。因此,在将TestingTable1
与TestingTable1
进行比较时,我需要涵盖这三个案例。 TestingTable1
是MAIN表,通过该表总是需要进行比较,这意味着TestingTable2
中的数据始终是准确的。
所以我需要显示下面的结果,如果不匹配其中任何一个,或者数据不在TestingTable1
中的所有 - TestingTable2
数据,那么它旁边就是{{} 1}}数据,以便我可以看到TestingTable1
与TestingTable2
相比有什么价值
BUYER_ID | ITEM_ID | CREATED_TIME | USER_ID | PRODUCT_ID | LAST_TIME
-----------+-----------------+---------------------------+----------------+--------------------+-----------------------
1345653 110909316904 2012-07-09 21:29:06 1345653 110909316904 2012-07-09 22:29:06
1345653 151851771618 2012-07-09 19:57:33 1345653 150851771618 2012-07-09 19:57:33
1345653 221065796761 2012-07-09 19:31:48 NULL NULL NULL
1345653 400307563710 2012-07-09 18:57:33 NULL NULL NULL
下面是我编写的查询,其中仅涵盖了我上面提到的two scenarios
,它工作正常,我将得到上面的输出,从输出中留下最后两行。但我需要在此(下面)查询中添加third scenario
,以便它提供如上所述的输出。
SELECT *
FROM (SELECT T2.buyer_id,
T2.item_id,
T2.created_time AS created_time,
subq.user_id,
subq.product_id,
subq.LAST_TIME
FROM TestingTable2 subq
JOIN TestingTable1 T2
ON T2.buyer_id = subq.user_id
AND subq.LAST_TIME = ( T2.created_time )
WHERE ( subq.product_id <> T2.item_id )
UNION ALL
SELECT T2.buyer_id,
T2.item_id AS item_id,
T2.created_time,
subq.user_id,
subq.product_id AS product_id,
subq.LAST_TIME
FROM TestingTable2 subq
JOIN TestingTable1 T2
ON T2.buyer_id = subq.user_id
AND subq.product_id = T2.item_id
WHERE ( subq.LAST_TIME <> ( T2.created_time ) )) finalResult
ORDER BY finalResult.BUYER_ID;
任何建议都将受到赞赏。
P.S。我在过去几天里几乎没有问过与JOIN相关的问题,但这只涉及我的两个场景,而不是我在此查询中需要的第三个场景。
更新: -
我不能对SQL使用NOT IN
或NOT EXISTS
语法,因为我正在使用Hive而Hive不支持NOT IN
或NOT EXISTS
,因此我需要其他方式来处理有这个。
我只需要使用我的查询来修改它以适用于Third Scenario,因为Hive将支持SQL语法。
下面是我的 SQL Fiddle ,它完成了我上面的两个场景,但不是第三个场景。任何人都可以帮我修改我的查询以便为第三种情况工作吗?
http://sqlfiddle.com/#!3/102dd/1/0。
表1中的数据应该在表2中,如果不存在,那么我需要在从Table1进行比较后显示数据之间的不匹配,并且有可能表1中的数据不在表2中,我也希望表明这一点。
更新了小提琴的输出http://sqlfiddle.com/#!3/102dd/3/0
BUYER_ID | ITEM_ID | CREATED_TIME | USER_ID | PRODUCT_ID | LAST_TIME
-----------+-----------------+---------------------------+----------------+--------------------+-----------------------
1345653 151851771618 July, 09 2012 19:57:33 1345653 150851771618 July, 09 2012 19:57:33
1345653 221065796761 July, 09 2012 19:31:48 1345653 221165796761 July, 09 2012 19:31:48
1345653 110909316904 July, 09 2012 21:29:06 1345653 110909316904 July, 09 2012 22:29:06
1345653 400307563710 July, 09 2012 18:57:33 NULL NULL NULL
1345653 310411560125 July, 09 2012 16:09:49 NULL NULL NULL
更新SQL错误导致错误
我用此查询替换了TestingTable1
-
(SELECT BUYER_ID, ITEM_ID, rank(BUYER_ID), CREATED_TIME
FROM (
SELECT BUYER_ID, ITEM_ID, CREATED_TIME
FROM testingtable1
where to_date(from_unixtime(cast(UNIX_TIMESTAMP(CREATED_TIME) as int))) = '2012-07-09'
DISTRIBUTE BY BUYER_ID
SORT BY BUYER_ID, CREATED_TIME desc
) T1
WHERE rank(BUYER_ID) < 5)
TestingTable2
使用此查询 -
(SELECT USER_ID, PROD_AND_TS.PRODUCT_ID as PRODUCT_ID, PROD_AND_TS.TIMESTAMPS as TIMESTAMPS FROM testingtable2 lateral view explode(PURCHASED_ITEM) exploded_table as PROD_AND_TS where to_date(from_unixtime(cast(PROD_AND_TS.TIMESTAMPS as BIGINT))) = '2012-07-09')
答案 0 :(得分:2)
如果由于DBMS限制而无法使用NOT IN
或@eggyal
发布的干净解决方案,则另一个选项可能是完全复制原始联合并在{{1}中使用这些结果}。
应用于您的sqlFiddle,以下语句将返回所需的结果。
SQL声明
LEFT JOIN
答案 1 :(得分:1)
尝试用SQL编写的这段代码。我已经在SQL Fiddle上测试了这个。
SELECT
tt1.buyer_id,tt1.item_id,tt1.created_time,
tt2.user_id,tt2.product_id,tt2.last_time
FROM
testingtable1 tt1 LEFT OUTER JOIN
testingtable2 tt2 ON
tt1.buyer_id = tt2.user_id
AND
tt1.item_id = tt2.product_id
AND
tt1.created_time = tt2.last_time
答案 2 :(得分:1)
此答案是对您的评论请求的回应:https://stackoverflow.com/a/11440651/1166147 我实际上已经在你的其他2个重复项中给出了这个答案,它创建了你显示的确切输出。这是我在这里写的第一个查询: https://stackoverflow.com/a/11440539/1166147 它在这里提到并解释了两次: https://stackoverflow.com/a/11398990/1166147
我将您的查询修改回我的并在您的SQLFiddle中运行它:
您的要求已经发展,如果TestingTable1确实始终是准确的数据,您现在可以只执行LEFT JOIN
。
SELECT *
FROM TestingTable1 A
LEFT JOIN TestingTable2 B ON A.BUYER_ID = B.USER_ID AND (B.LAST_TIME = A.Created_TIME OR B.PRODUCT_ID = A.ITEM_ID)
编辑评论
MOCK SCENARIOS
SCENARIO|| TABLE1 || TABLE2
----------------------------------------------------------
SCENARIO|| BUYER ITEM TIME || USER PRODUCT TIME
1 || 1 A 09 || 1 Z 09
2 || 1 B 10 || NO RECORD IN TABLE 2
3 || 1 C 10 || 1 C 02
4 || 1 D 12 || NO RECORD IN TABLE 2
5 || 1 E 01 || 1 E 01
6 || NO RECORD IN TABLE 1 || 1 Y 05
您要求的是SQL解决方案 - 但这不是一个SQL问题。您排除了给您的有效SQL答案,因为您无法在您的环境中使用它们,然后再次重新打开相同的问题。这是一个HQL / HIVE问题。是的,有一些相似之处,但存在一些差异。
看起来HQL会支持这样的东西,虽然我无法测试,而SQLFiddle也无法对此进行测试。您必须弄清楚如何在HQL中执行ISNULL
或COALESCE
,如select *旁边的注释所示。如果那里存在非空值,这将“合并”结果并从非空的值返回值。我相信HQL支持ISNULL:
select * --BUYER_ID, isNull(B.USER_ID,C.USER_ID)
from
(select BUYER_ID,ITEM_ID ,Created_TIME from TestingTable1) a
left join
(SELECT USER_ID,PRODUCT_ID, last_time
FROM TestingTable2 ) b on(a.BUYER_ID = b.user_id and B.last_time = A.Created_TIME)
left join
(SELECT USER_ID,PRODUCT_ID, last_time
FROM TestingTable2 ) c on(a.BUYER_ID = c.user_id and c.PRODUCT_ID = A.ITEM_ID)
这是另一个可能给你一些想法的TSQL答案。我永远不会在TSQL中使用它,但实际上它可以工作。
SELECT A.BUYER_ID,A.ITEM_ID,CREATED_TIME,COALESCE(B.USER_ID,X.USER_ID,Y.USER_ID),
COALESCE(B.PRODUCT_ID,X.PRODUCT_ID,Y.PRODUCT_ID)
,COALESCE(B.last_time,X.last_time,Y.last_time)
FROM TestingTable1 A
LEFT JOIN TestingTable2 B ON A.BUYER_ID = B.USER_ID AND B.PRODUCT_ID = A.ITEM_ID
AND B.last_time = A.Created_TIME
LEFT JOIN( SELECT USER_ID,PRODUCT_ID, last_time
FROM TestingTable1 A
LEFT JOIN TestingTable2 B ON A.BUYER_ID = B.USER_ID AND B.last_time = A.Created_TIME
WHERE ISNULL(B.PRODUCT_ID,0) <> A.ITEM_ID AND B.USER_ID IS NOT NULL) X ON
X.USER_ID = A.BUYER_ID AND A.Created_TIME = X.last_time
LEFT JOIN( SELECT USER_ID,PRODUCT_ID, last_time
FROM TestingTable1 A
LEFT JOIN TestingTable2 B ON A.BUYER_ID = B.USER_ID AND ISNULL( B.PRODUCT_ID,0) = A.ITEM_ID
WHERE B.last_time <> A.Created_TIME AND B.USER_ID IS NOT NULL) Y ON
A.BUYER_ID = Y.USER_ID AND A.ITEM_ID = Y.PRODUCT_ID
答案 3 :(得分:0)
听起来你正在寻找的是全外连接。我没有在你的帖子中看到你正在使用什么类型的数据库,所以我无法发布确切的语法,但是这个链接可能指向正确的方向:
http://www.w3resource.com/sql/joins/perform-a-full-outer-join.php
具体看底部的图表。