SQLの1次式

例のとおりに操作する場合は、スクリプトbaggageschema_loaddata.sqlをダウンロードして、次に示すように実行します。このスクリプトにより、例で使用する表が作成され、表にデータがロードされます。

KVSTOREまたはKVLiteを起動し、SQL.shellを開きます。
java -jar lib/kvstore.jar kvlite -secure-config disable
java -jar lib/sql.jar -helper-hosts localhost:5000 -store kvstore
loadコマンドを使用して、スクリプトを実行します。
load -file baggageschema_loaddata.sql

カッコ内の式

カッコ内の式は、主に演算子間のデフォルトの優先順位を変更するために使用します。また、構文的にあいまいになるような方法で式を混在させるための構文支援としても使用されます。

例: JFKで搭乗するかJFKを通過し、到着地がMADまたはVIEである乗客のフルネーム、タグ番号および経路詳細をフェッチします。
SELECT fullName, bag.bagInfo.tagNum, 
bag.bagInfo.routing, 
bag.bagInfo[].flightLegs[].fltRouteDest 
FROM BaggageInfo bag 
WHERE bag.bagInfo.flightLegs[].fltRouteSrc=any "JFK" AND 
(bag.bagInfo[].flightLegs[].fltRouteDest=any "MAD" OR
bag.bagInfo[].flightLegs[].fltRouteDest=any "VIE" )

説明: 乗客のフルネーム、タグ番号および経路詳細をフェッチする必要があります。最初のフィルタ条件は、搭乗地点またはトランジットがJFKであることです。これが満たされた後の2番目のフィルタ条件は、到着地がMADまたはVIEであることです。OR条件を使用して、到着地の値をフィルタします。

出力:
{"fullName":"Dierdre Amador","tagNum":"17657806240229","routing":"JFK/MAD","fltRouteDest":"MAD"}
{"fullName":"Rosalia Triplett","tagNum":"17657806215913","routing":"JFK/IST/VIE","fltRouteDest":["IST","VIE"]}
{"fullName":"Kendal Biddle","tagNum":"17657806296887","routing":"JFK/IST/VIE","fltRouteDest":["IST","VIE"]}

CASE式

検索されたCASE式は、従来のプログラミング言語のif-then-else文に似ています。これは、いくつかのWHEN-THENペアで構成され、末尾にオプションのELSE句が続きます。各WHEN式は条件です。つまり、BOOLEANを返す必要があります。THEN式およびELSE式は、項目の順序を返す場合があります。CASE式は、最初にWHEN式を上から下に評価して、最初にtrueを返すものまで評価されます。trueを返すのがi番目のWHEN式の場合、i番目のTHEN式が評価され、その結果はCASE式全体の結果になります。WHEN式でtrueが返されない場合、ELSEがあれば、その式が評価され、その結果がCASE式全体の結果となります。それ以外の場合、CASE式の結果は空の順序になります。

例:
SELECT
    fullName,
    CASE
        WHEN NOT exists bag.bagInfo.flightLegs[0]
        THEN "you have no bag info"
        WHEN NOT exists bag.bagInfo.flightLegs[1]
        THEN "you have one hop"
        WHEN NOT exists bag.bagInfo.flightLegs[2]
        THEN "you have two hops."
        ELSE "you have three hops."
    END AS NUMBER_HOPS
FROM BaggageInfo bag WHERE ticketNo=1762340683564

説明: CASE文を使用して、乗客のbagInfoのトランジットがいくつあるかを確認する必要があります。flightLegs配列に要素がない場合、その乗客には手荷物データがありません。flightLegs配列に1つの要素のみがある場合、トランジット・ポイントは1つのみ存在します。同様に、flightLegs配列に2つの要素がある場合、2つの中継点があります。それ以外の場合は、3つのトランジット・ポイントがあります。ここでは、1つの手荷物のトランジット・ポイントまたは中継点は最大で3つと想定します。

出力:
{"fullName":"Mary Watson","NUMBER_HOPS":"you have two hops."}
例2: 乗客の既存のtagNum値が文字列でない場合、その値を更新するようにシステムに警告する問合せを記述します。
SELECT bag.bagInfo[].tagNum,
CASE
   WHEN bag.bagInfo[0].tagNum is of type (NUMBER)
   THEN "Tagnumber is not a STRING. Update the data"
   ELSE "Tagnumber has correct datatype"
   END AS tag_NUM_TYPE
FROM BaggageInfo bag 

説明: bagInfoスキーマ内の乗客のtagNumはSTRINGデータ型です。ただし、アプリケーションが誤ってtagNumの値としてNUMBER値を取得する可能性があります。問合せではis of type演算子を使用してこれを取得し、既存の値が文字列でない場合はtagNumを更新するようシステムに指示します。

出力(簡潔にするために数行のみ表示されています)。
{"tagNum":"17657806240001","tag_NUM_TYPE":"Tagnumber has correct datatype"}
{"tagNum":"17657806224224","tag_NUM_TYPE":"Tagnumber has correct datatype"}
{"tagNum":17657806243578,"tag_NUM_TYPE":"Tagnumber is not a STRING. Update the data"}
{"tagNum":"1765780623244","tag_NUM_TYPE":"Tagnumber has correct datatype"}

CAST式

CAST式は、可能な場合、特定のターゲット・タイプの新しい項目をその入力順序の項目から作成します。たとえば、CAST式を使用して、STRINGをTIMESTAMP(0)に変換できます。

CAST式の規則は次のとおりです。
  • 入力項目のタイプがターゲット項目タイプと等しい場合、キャストはno-opであり、入力項目自体が返されます。
  • ターゲット・タイプがJSON以外のワイルドカード・タイプで、入力項目のタイプがワイルドカード・タイプのサブタイプである場合、キャストはno-opです。
  • ターゲット・タイプがJSONの場合、入力項目がJSON以外のアトミック型であるとエラーが発生します。
  • ターゲット・タイプが配列タイプの場合、入力項目が配列でないとエラーが発生します。
  • ターゲット・タイプが文字列の場合、入力項目は任意のタイプにすることができます。つまり、すべての項目を文字列にキャストできます。タイムスタンプの場合、文字列値はUTCであり、uuuu-MM-dd['T'HH:mm:ss]という形式です。
  • ターゲット・タイプが文字列以外のアトミック型である場合、入力項目もアトミックである必要があります。
      • integerとlongは、タイムスタンプにキャストできます。入力値は、1970年1月1日、00:00:00 GMTからのミリ秒数として解釈されます。
      • 文字列項目は、他のすべてのアトミック型にキャスト可能です。キャストが成功するかどうかは、ターゲット・タイプのドメインに属する値に実際の文字列値を解析できるかどうかによって決まります。
      • タイムスタンプ項目は、すべてのタイムスタンプ・タイプにキャストできます。ターゲット・タイプの精度が入力項目よりも小さい場合、結果のタイムスタンプは、ターゲット精度の入力タイムスタンプに最も近いものになります。
  • STRINGをTIMESTAMPにキャストするために、入力にISO-8601形式のSTRING値がある場合は、SQLランタイムによってTIMESTAMPデータ型に自動的に変換されます。

    ノート:

    ISO8601は、日付、時刻および継続時間を表すために国際的に受け入れられている方法について説明しています。

    構文: 日付と時刻: YYYY-MM-DDThh:mm:ss[.s[s[s[s[s[s]]]]][Z|(+|-)hh:mm]

    ここで
    • YYYYは、4桁の10進数で年を指定します
    • MMは、00から12までの2桁の10進数で月を指定します
    • DDは、00から31までの2桁の10進数で日を指定します
    • hhは、00から23までの2桁の10進数で時間を指定します
    • mmは、00から59までの2桁の10進数で分を指定します
    • ss[.s[s[s[s[s]]]]]は、00から59までの2桁の10進数で秒を指定します。オプションで、小数点と1から6桁の10進数(秒の小数部を表す)を続けます。
    • Zは、UTC時間(タイムゾーン0)を指定します。(-00:00ではなく、+00:00で指定することもできます。)
    • (+|-)hh:mmは、タイムゾーンをUTCとの差として指定します。(+または-のいずれか1つは必須です。)
例1: 予約コードDN3I4Qの乗客の手荷物到着日をTIMESTAMP(3)形式でフェッチします。
SELECT CAST (bag.bagInfo.bagArrivalDate AS Timestamp(3))
AS BAG_ARRIVING_DATE 
FROM BaggageInfo bag WHERE bag.confNo=DN3I4Q

説明: bagArrivalDateはSTRINGです。CASTを使用して、このフィールドをTIMESTAMP形式に変換します。

出力:
{"BAG_ARRIVING_DATE":"2019-02-15T21:21:00.000Z"}
例2: 2019年以降に運搬されたすべての乗客手荷物についてフルネームとタグ番号をフェッチします。
SELECT fullName, bag.ticketNo, 
bag.bagInfo[].bagArrivalDate 
FROM BaggageInfo bag WHERE
exists bag.bagInfo[$element.bagArrivalDate >="2019-01-01T00:00:00"]

説明: 2019年以降に運搬された手荷物の詳細をフィルタして表示します。flightLegs配列の各要素の手荷物到着日が、指定されたタイムスタンプ(2019-01-01T00:00:00)と比較されます。ここでは、bagArrivalDateがSTRINGで、静的タイムスタンプ値と直接比較されるため、キャストは暗黙的です。暗黙的なキャストを実行できる場合、明示的なCAST関数は必要ありません。ただし、データはYYYY-MM-DDTHH:MI:SSの形式にする必要があります。次に、EXISTS条件を使用して、このタイムスタンプ条件に合うbagInfoが存在するかどうかを確認します。

出力:
{"fullName":"Kendal Biddle","ticketNo":1762377974281,"bagArrivalDate":"2019-03-05T12:00:00Z"}
{"fullName":"Lucinda Beckman","ticketNo":1762320569757,"bagArrivalDate":"2019-03-12T15:05:00Z"}
{"fullName":"Adelaide Willard","ticketNo":1762392135540,"bagArrivalDate":"2019-02-15T21:21:00Z"}
{"fullName":"Raymond Griffin","ticketNo":1762399766476,"bagArrivalDate":"2019-02-03T08:09:00Z"}
{"fullName":"Elane Lemons","ticketNo":1762324912391,"bagArrivalDate":"2019-03-15T10:13:00Z"}
{"fullName":"Zina Christenson","ticketNo":1762390789239,"bagArrivalDate":"2019-02-04T10:08:00Z"}
{"fullName":"Zulema Martindale","ticketNo":1762340579411,"bagArrivalDate":"2019-02-25T20:15:00Z"}
{"fullName":"Dierdre Amador","ticketNo":1762376407826,"bagArrivalDate":"2019-03-07T13:51:00Z"}
{"fullName":"Henry Jenkins","ticketNo":176234463813,"bagArrivalDate":"2019-03-02T13:18:00Z"}
{"fullName":"Rosalia Triplett","ticketNo":1762311547917,"bagArrivalDate":"2019-02-12T07:04:00Z"}
{"fullName":"Lorenzo Phil","ticketNo":1762320369957,"bagArrivalDate":["2019-03-12T15:05:00Z","2019-03-12T16:25:00Z"]}
{"fullName":"Gerard Greene","ticketNo":1762341772625,"bagArrivalDate":"2019-03-07T16:01:00Z"}
{"fullName":"Adam Phillips","ticketNo":1762344493810,"bagArrivalDate":"2019-02-01T16:13:00Z"}
{"fullName":"Doris Martin","ticketNo":1762355527825,"bagArrivalDate":"2019-03-22T10:17:00Z"}
{"fullName":"Joanne Diaz","ticketNo":1762383911861,"bagArrivalDate":"2019-02-16T16:13:00Z"}
{"fullName":"Teena Colley","ticketNo":1762357254392,"bagArrivalDate":"2019-02-13T11:15:00Z"}
{"fullName":"Michelle Payne","ticketNo":1762330498104,"bagArrivalDate":"2019-02-02T23:59:00Z"}
{"fullName":"Mary Watson","ticketNo":1762340683564,"bagArrivalDate":"2019-03-14T06:22:00Z"}
{"fullName":"Omar Harvey","ticketNo":1762348904343,"bagArrivalDate":"2019-03-02T16:09:00Z"}
{"fullName":"Fallon Clements","ticketNo":1762350390409,"bagArrivalDate":"2019-02-21T14:08:00Z"}
{"fullName":"Lisbeth Wampler","ticketNo":1762355854464,"bagArrivalDate":"2019-02-10T10:01:00Z"}

順序変換式

順序変換式は、順序を別の順序に変換します。構文的には、seq_transformという名前の関数のように見えます。最初の引数は、変換する順序(入力順序)を生成する式であり、2番目の引数は入力順序の各項目に対して計算されるマッパー式です。seq_transform式の結果は、マッパー式の各評価によって生成される順序の連結となります。マッパー式は、$変数を介して現在の入力項目にアクセスできます。

例: ticketNoごとに、そのticketNoの手荷物に対して実行されたすべてのアクションを含むフラット配列をフェッチします。
SELECT seq_transform(l.bagInfo[],
      seq_transform(
          $sq1.flightLegs[],
          seq_transform(
              $sq2.actions[],
              {
                "at" : $sq3.actionAt,
                "action" : $sq3.actionCode,
                "flightNo" : $sq2.flightNo,
                "tagNum" : $sq1.tagNum
              }
          )
      )
  ) AS actions
FROM baggageInfo l WHERE ticketNo=1762340683564

説明: 表の行に格納されたJSONドキュメントを変換するために、順序変換式を使用できます。このような場合、相互にネストされている複数の順序変換式を使用することがよくあります。ここで、内部の順序変換マッパー式は、外部の順序変換の現在の項目にアクセスすることが必要な場合があります。これを可能にするために、各順序変換式Sは$sqNという名前の変数を宣言します。ここで、Nは、外部順序変換式内の式Sのネストのレベルです。$sqNは基本的に$のシノニムであり、入力式Sによって返される項目にバインドされます。ただし、$sqNは、式S内でネストできる他の順序変換式によりアクセスできます。

出力:
{ 
 "actions":[ 
   {"action":"ONLOAD to HKG","at":"YYZ","flightNo":"BM267","tagNum":"17657806299833"},
   {"action":"BagTag Scan at YYZ","at":"YYZ","flightNo":"BM267","tagNum":"17657806299833"},
   {"action":"Checkin at YYZ","at":"YYZ","flightNo":"BM267","tagNum":"17657806299833"},
   {"action":"Offload to Carousel at BLR","at":"BLR","flightNo":"BM115","tagNum":"17657806299833"},
   {"action":"ONLOAD to BLR","at":"HKG","flightNo":"BM115","tagNum":"17657806299833"},
   {"action":"OFFLOAD from HKG","at":"HKG","flightNo":"BM115","tagNum":"17657806299833"} 
 ]
}