簡體   English   中英

如何將此 JSON 導入 2 個單獨的表中?

[英]How do I import this JSON into 2 separate tables?

我正在處理此端點的數據集: https ://db.ygoprodeck.com/api/v7/cardinfo.php

我需要將此 JSON 導入 2 個表中: CardsSets 下面是每個表的架構。

id
name
type
desc
race
archetype
atk
def
ban_tcg
ban_ocg
ban_goat
level
attribute
linkval
image_url
image_url_small
pendulum_scale
linkmarker_topleft --deeper than single level
linkmarker_top --deeper than single level
linkmarker_topright --deeper than single level
linkmarker_left --deeper than single level
linkmarker_right --deeper than single level
linkmarker_bottomleft --deeper than single level
linkmarker_bottom --deeper than single level
linkmarker_bottomright --deeper than single level

對於Cards表,我可以使用下面的代碼將任何單級數據插入到表中,但是如何更深入地進入linkmarkers節點並將找到的值返回到正確的列中? 例如,對於數據集中的第 8614 行, linkmarkers節點只有 1 個鍵,其值為“Top”,因此我需要腳本將“Top”插入到linkmarker_top列中,並將所有其他linkmarker列插入 null。

Declare @JSON varchar(max)
Declare @JSON2 varchar(max)
SELECT @JSON=BulkColumn
FROM OPENROWSET (BULK 'C:\Users\User\Desktop\YGOCards.json', SINGLE_CLOB) import
SELECT @JSON2 = value 
FROM OPENJSON (@JSON)
select * into #cards
from openjson(@JSON2)
with (
    [id] nvarchar(4000)
    , [name] nvarchar(1000)
    , [type] nvarchar(1000)
    , [desc] nvarchar(1000)
    , [race] nvarchar(1000)
    , [archetype] nvarchar(1000)
    , [atk] nvarchar(1000)
    , [def] nvarchar(1000)
    , [ban_tcg] nvarchar(1000)
    , [ban_ocg] nvarchar(1000)
    , [ban_goat] nvarchar(1000)
    , [level] nvarchar(1000)
    , [attribute] nvarchar(1000)
    , [linkval] nvarchar(1000)
)

示例輸出行:

id ...   linkmarker_topleft  linkmarker_top  linkmarker_topright  linkmarker_left...
94259633 null                Top             null                 null 

id
set_name
set_code
set_rarity
set_rarity_code

對於Sets表,我基本上想創建一個表,在其中將每個id與每張卡來自的card_set相關聯,但我不確定如何執行此操作。 所以以數據集的第一行為例:

示例輸出行:

id        set_name              set_code    set_rarity...
34541863  Force of the Breaker  FOTB-EN043  Common

對於linkmarkers ,您可以將其作為 JSON 數組拉出,然后在CROSS APPLY中,您可以使用OPENJSON將其切碎並進行旋轉。

對於card_sets數組,你可以從原來的cards數組中CROSS APPLY它,從而同時拉出cards.id 這可以成為您表的外鍵。

SELECT
  c.*,
  lm.*
INTO #cards
FROM OPENJSON(@json, '$.data')
  WITH (
    [id] int
    , [name] nvarchar(1000)
    , [type] nvarchar(1000)
    , [desc] nvarchar(1000)
    , [race] nvarchar(1000)
    , [archetype] nvarchar(1000)
    , [atk] nvarchar(1000)
    , [def] nvarchar(1000)
    , [ban_tcg] nvarchar(1000)
    , [ban_ocg] nvarchar(1000)
    , [ban_goat] nvarchar(1000)
    , [level] nvarchar(1000)
    , [attribute] nvarchar(1000)
    , [linkval] nvarchar(1000)
    , linkmarkers nvarchar(max) AS JSON
  ) c
CROSS APPLY (
    SELECT
       MIN(CASE WHEN mark.value = 'Top'          THEN 1 END) [Top]
      ,MIN(CASE WHEN mark.value = 'Top-Left'     THEN 1 END) [Top-Left]
      ,MIN(CASE WHEN mark.value = 'Top-Right'    THEN 1 END) [Top-Right]
      ,MIN(CASE WHEN mark.value = 'Bottom'       THEN 1 END) [Bottom]
      ,MIN(CASE WHEN mark.value = 'Bottom-Left'  THEN 1 END) [Bottom-Left]
      ,MIN(CASE WHEN mark.value = 'Bottom-Right' THEN 1 END) [Bottom-Right]
    FROM OPENJSON(c.linkmarkers) mark
) lm;

  
SELECT
  c.id card_id,
  s.*
INTO #sets
FROM OPENJSON(@json, '$.data')
  WITH (
    [id] int,
    card_sets nvarchar(max) AS JSON
  ) c
CROSS APPLY OPENJSON(c.card_sets)
  WITH (
    set_name nvarchar(100),
    set_code nvarchar(10),
    set_rarity nvarchar(100),
    set_rarity_code nvarchar(10)
  ) s;

請注意以下事項:

  • 您可以對其他內部數組執行相同的操作。
  • 使用 JSON 路徑直接跳轉到$.data
  • 如果您需要獲取數組位置,您可以使用不帶WITH模式的OPENJSON ,它為您提供每個對象的數組索引。
  • 更好地選擇數據類型。
  • 理想情況下,您將使用主鍵和外鍵創建固定表,而不是插入到#臨時表中。

db<>小提琴

這是我將記錄插入卡表的邏輯(使用javascript):

  1. grep 所有記錄
  2. 如果找到linkmarkers ,添加新字段名稱保存記錄
  3. 插入記錄

示例代碼:

const jp = require('jsonpath')
const source = require("./source.js") // reference from cardinfo.php

async function main() {
  // Cards
  let query = jp.query(source, "$.data[*]")
  query = query.map((x) => {
    if(x.linkmarkers){
      (x.linkmarkers).forEach((y) => {
        console.log(`linkmarker_${y.toLowerCase()}`)
        x[`linkmarker_${y.toLowerCase()}`] = y
      })      
    }
    return x
  })

  // Set Table
  let table = [["id", "nams", "linkmarket_topleft", "linkmarket_top", "linkmarker_bottom"]]
  for(let i=0; i<query.length; i++){
    let { id, name, linkmarket_topleft, linkmarket_top, linkmarker_bottom } = query[i]
    
    // Your insert SQL query
    // ...
  }
}
main()

第 2 點之后的 csv 結果: 在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM