0

以下のような内容のテーブルが 2 つあります。

Table 1:
ID1     ID2     ID3    ID4                NAME    DESCR   STATUS        date   
1    -12134    17773    8001300701101    name1    descr1    INACTIVE    20121203
2    -12136    17773    8001300701101    name1    descr1    INACTIVE     20121202
3    -12138    17785    9100000161822    name3    descr3    INACTIVE    20121201
4    -12140    17785    9100000161822    name3   descr3    ACTIVE        20121130
5    -12142    17787    8000500039106    name4    descr4    ACTIVE        20121129

Table2:
ID1    ID2         ID3        ID4       NAME    DESCR  
0    17781    17773    8001300701101    name1    descr1
0    17783    17783    8001300060109    name2    descr2
0    17785    17785    9100000161822    name3    descr3
0    17787    17787    8000500039106    name4    descr4
0    17789    17789    0000080052364    name5    descr5

私は結果を下回ろうとしています。

ID3        ID4            NAME     DESCR      STATUS        date        
17773    8001300701101    name1    descr1      INACTIVE    20121202
17783    8001300060109    name2    descr2      NULL        NULL
17785    9100000161822    name3    descr3      ACTIVE      20121201
17787    8000500039106    name4    descr4      ACTIVE      20121129
17789    0000080052364    name5    descr5      NULL        NULL

上記の i/p および o/p に従って、列 id3、id4、name、および desc に基づいて 2 つのテーブルを結合する必要があります。アクティブなレコードが存在する場合は、アクティブなレコードを返す必要があります。ただし、非アクティブなレコードのみが存在する場合は、最も古い非アクティブなレコードを結合する必要があります。

私が望んでいた答えに近づかなくなったさまざまなクエリを試しました。結合された 4 つの列はすべて非プライマリ フィールドですが、null ではありません。2 つのテーブル間には、1 対多または多対多の関係があります。

私は Apache phoenix に取り組んでおり、ソリューションが Hadoop Mapreduce または Apache Spark にある場合も問題ありません。

私が書いたサンプルクエリは次のとおりです。

Select table2.*, table1.status, table1.date 
From table1 Right outer join table2 on table1.id3 = table2.id3 
            and  table1.id4 = table2.id4 
            and table1.name = table2.name 
            and table1.descr = table2.descr 
Order by (status) and order by (date)

誰でも私を助けてもらえますか?

4

2 に答える 2

1

テーブル 1 に対して直接結合を行うことはできません。代わりに、テーブル 1 の複数のクエリに対して結合する必要があり、それら自体が結合されています。私の計算では、あなたはしなければならないでしょう:

  1. ID3、ID4 などごとにテーブル 1dateのレコードの最小値を見つけるためのクエリ。ACTIVE
  2. dateテーブル 1のINACTIVEレコードの最小値を検索するクエリ
  3. 上記の 2 つのクエリ間の完全外部結合
  4. coalesceACTIVEINACTIVEフィールドを選択します。

このようなもの:

val cookedTable1 = table1.filter(
  $"STATUS" === "ACTIVE"
).groupBy(
  $"ID3", $"ID4", $"NAME", $"DESCR", $"STATUS"
).agg(
  $"ID3", $"ID4", $"NAME", $"DESCR", $"STATUS", min($"date") as "date"
).join(
  table1.filter(
    $"STATUS" === "INACTIVE"
  ).groupBy(
    $"ID3", $"ID4", $"NAME", $"DESCR", $"STATUS"
  ).agg(
    $"ID3", $"ID4", $"NAME", $"DESCR", $"STATUS", min($"date") as "date"
  ).select(
    $"ID3" as "ID3r", $"ID4" as "ID4r", $"NAME" as "NAMEr", $"DESCR" as "DESCRr",
    $"STATUS" as "STATUSr", $"date" as "dater"
  ),
  $"ID3" === $"ID3r" and $"ID4" === $"ID4r" and $"NAME" === $"NAMEr" and $"DESCR" === $"DESCRr", 
  "full_outer"
)
.select(
  coalesce($"ID3", $"ID3r") as "ID3", 
  coalesce($"ID4",$"ID4r") as "ID4", 
  coalesce($"NAME", $"NAMEr") as "NAME",
  coalesce($"DESCR", $"DESCRr") as "DESCR",
  coalesce($"STATUS", $"STATUSr") as "STATUS",
  coalesce($"date", $"dater") as "date"
)

上記の表 1 の内容を考えると、結果は次のようになります。

cookedTable1.show

ID3   ID4           NAME  DESCR  STATUS   date
17785 9100000161822 name3 descr3 ACTIVE   20121130
17787 8000500039106 name4 descr4 ACTIVE   20121129
17773 8001300701101 name1 descr1 INACTIVE 20121202

cookedTable1の代わりにを使用しtable1て、以前と同じクエリを実行します。

cookedTable1.registerTempTable("cookedTable1")
val results = sqlContext("Select table2.*, cookedTable1.status, cookedTable1.date
  From cookedTable1 Right outer join table2 on cookedTable1.id3 = table2.id3
    and cookedTable1.id4 = table2.id4
    and cookedTable1.name = table2.name
    andcookedTable1.descr = table2.descr"
)

これにより、最初に探していた結果が得られるはずです。

于 2015-05-31T05:18:40.097 に答える
0

私はスパークについてしか話せません。右外部結合と 4 つの結合列に関して、クエリは正しく表示されます。

Spark(およびANSI sqlのAFAIK)では、順序はあなたが示す方法ではなく、代わりに:

order by status, date
于 2015-05-30T19:12:44.683 に答える