2016-11-03 5 views
0

HDP-2.5.0.0にSQL Serverクエリを適用CROSS Ambari 2.4.0.1を使用してハイブ

ハイブテーブルReportSettingは、次のとおりです。

id int 

serializedreportsetting String 

列 'serializedreportsetting' XMLデータ型はですソースSQL ServerのDBが、Sqoopインポート時に文字列に変換され、これはSQL Serverでどのように見えるかです:ハイブ表で

<ReportSettings4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Trigger> 
    <Manual>true</Manual> 
    </Trigger> 
<StartTime> 
    <Year>8</Year> 
    <Month>1</Month> 
    <Day>1</Day> 
    <Hour>0</Hour> 
    <Minute>0</Minute> 
    </StartTime> 
    <ReportPeriod> 
    <Month>0</Month> 
    <Day>0</Day> 
    <Hour>0</Hour> 
    <Minute>5</Minute> 
    </ReportPeriod> 
    <Theft> 
    <DigitalInput>true</DigitalInput> 
    <Can>false</Can> 
    </Theft> 
    <SequenceNo>0</SequenceNo> 
</ReportSettings4> 

<ReportSettings4 xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Trigger><Manual>true</Manual></Trigger><StartTime><Year>8</Year><Month>12</Month><Day>31</Day><Hour>23</Hour><Minute>34</Minute></StartTime><ReportPeriod><Month>0</Month><Day>0</Day><Hour>4</Hour><Minute>0</Minute></ReportPeriod><Theft><DigitalInput>false</DigitalInput><Can>false</Can></Theft><SequenceNo>3</SequenceNo></ReportSettings4> 

SQL Server上で正常に動作クエリは:私は/次の操作を行うと考えることができ

SELECT 
r.VehicleId 
,rs.value('(Trigger/Manual)[1]', 'bit') AS RS_Trigger_Manual, ,CAST(CONCAT(CASE WHEN rs.value('(StartTime/Year)[1]', 'int') < 10 THEN CONCAT('200',rs.value('(StartTime/Year)[1]', 'int')) ELSE CONCAT('20',rs.value('(StartTime/Year)[1]', 'int')) END,'-',rs.value('(StartTime/Month)[1]', 'int'),'-',rs.value('(StartTime/Day)[1]', 'int'),' ',rs.value('(StartTime/Hour)[1]', 'int'),':',rs.value('(StartTime/Minute)[1]', 'int'),':','00.000') AS datetime) AS RS_StartTime 
,rs.value('(ReportPeriod/Month)[1]', 'int') AS RS_ReportPeriod_Month 
,rs.value('(ReportPeriod/Day)[1]', 'int') AS RS_ReportPeriod_Day 
,rs.value('(ReportPeriod/Hour)[1]', 'int') AS RS_ReportPeriod_Hour 
,rs.value('(ReportPeriod/Minute)[1]', 'int') AS RS_ReportPeriod_Minute 
,rs.value('(Theft/DigitalInput)[1]', 'bit') AS RS_Theft_DigitalInput 
,rs.value('(Theft/Can)[1]', 'bit') AS RS_Theft_Can,rs.value('(SequenceNo)[1]', 'int') 

AS RS_SequenceNo FROM ReportSetting r 
    CROSS APPLY SerializedReportSetting.nodes('/*') AS ReportSettings(rs) 

  1. 適用CROSSを使用するには、私はあることをlateral viewニーズを推測ここでは配列としてserializedreportsettingを持っていないので、explode()は動作しません。私は正しい方向に
  2. を考えているならば、誰かが検証することができ、私は単にbuilt-in xpath udfを使用して列としてserializedreportsetting内のデータを取得しようとしました、しかし、私はすべてのレコードを取得しない、次のように、いくつかの試験は、次のとおりです。

    ReportSettingの制限1からxpath(SerializedReportSetting、 '/ *')を選択します。

    ReportSettingの制限1からxpath(SerializedReportSetting、 '/ ReportSettings4')を選択します。

    ReportSettingからxpath(SerializedReportSetting、 '/ Trigger/Manual')を選択します。

********** UPDATE-1 **********

私は上記の課題を処理するためにREGEXP_REPLACEを使用:

SELECT id, 
    xpath_string(SerializedReportSetting,'/ReportSettings/Trigger/Manual')  AS RS_Trigger_Manual, 
    xpath_string(SerializedReportSetting,'/ReportSettings/Trigger/DriveChange') AS RS_Trigger_DriveChange 
FROM 
    (SELECT id, 
    regexp_replace(SerializedReportSetting, 'ReportSettings+\\d','ReportSettings') AS SerializedReportSetting 
    FROM reportsetting 
    WHERE id IN (1701548,3185,1700231,1700232) 
) reportsetting_regex; 

答えて

1
xpath

は、彼らが明示的に言う:

xpath()関数は常に文字列のハイブ配列を返します。 xpath(SerializedReportSetting,'/ReportSettings4/Trigg‌​er/Manual/text()') from ReportSetting limit 1;

、あるいはより良いオプションがxpath_booleanを使用することです:非テキスト値の式の結果(例えば、別のXMLノード)関数は、あなたがいずれかのことができ、使用、空の配列

が返されます/ xpath_int

xpath_boolean - XPath式が真と評価された場合、または一致するノードが発見された場合 trueを返します。一致が見つからない場合 これらの機能をxpath_long

xpath_boolean(SerializedReportSetting,'/ReportSettings4/Trigg‌​er/Manual') from ReportSetting limit 1;

xpath_short、xpath_intは、整数の数値、または値ゼロを返す、または一致が発見されたが、値は、非あります数値。 数学演算がサポートされています。値が戻り値の型をオーバーフローする場合、型の最大値が返されます。

xpath_int(SerializedReportSetting,'/ReportSettings4/ReportPeriod/Month') from ReportSetting limit 1;

+0

SerializedReportSettingはReportSettings、ReportSettings1、ReportSettings2、ReportSettings3とReportSettings4を持つことができるので、 '正規表現' を扱うことができる汎用的なXPath式を記述することが可能ですか? –

+0

'xpath_int(SerializedReportSetting、 '/ ReportSettings */ReportPeriod/Month')'のようなものが動作するかどうかは、xpathドキュメントからわかりません –

+1

私は回避策を考えました。 'xpath_int'を呼び出す前にxmlから数値を削除します。 –

関連する問題