programing

MySQL JSON: 하위 배열에서 형제 요소의 값 찾기

newstyles 2023. 8. 7. 22:22

MySQL JSON: 하위 배열에서 형제 요소의 값 찾기

저는 다음과 같은 (의사)J를 가지고 있습니다.My MariaDB 10.2의 JSON(롱텍스트) 유형 열에 있는 SON

{"order":
    {"otherstuff":...},
    {"dates":
        [
            {
            "typeId":2,
            "date":"2019-05-21 09:00:00"
            },
            {
            "typeId":4,
            "date":"2019-05-21 10:00:00"
            }
        ]
    }
}

제가 필요한 것은 어떤 타입이 필요한지 아는 동안 주문 날짜입니다(4).주문에는 typeId로 식별되는 날짜가 여러 개 있을 수 있습니다. typeId 4가 항상 두 번째 위치에 있는 것은 아닙니다.

SELECT JSON_UNQUOTE(JSON_SEARCH(`json`, 'one', 4, NULL, '$.dates[*].typeId'))
// gives me: $.dates[1].typeId

내가 지금 처음 생각한 것이었습니다.REPLACEtypeId에 날짜가 지정되어 있지만 혼합된 데이터 정렬에 대한 불만이 있습니다.여기서 '날짜' 값을 어떻게 (더 우아하게) 참조해야 합니까?

또한, 쿼리는 다음의 표현이어야 합니다.GENERATED내 테이블에 있는 열.날짜 id4가 모든 주문에 반드시 있는 것은 아니기 때문에, 저는 다음과 같이 시도했습니다.

SELECT IF(4 IN (JSON_EXTRACT(json, '$.dates[*].typeId')), 'yes', 'no')
// above condition evaluates to [2, 4]

저는 '['와 ']'를 잘라냈지만, 4가 배열의 첫 번째인 경우에만 '예'가 표시됩니다(배열입니까?).따라서(괄호 없음):

[4, 7]-> 예

[2, 4]-> 아니요

저는 이것이 가치의 배열이 아니라 문자열로 인식된다고 가정합니다.그렇다면 바늘이 첫 번째 위치에 있으면 왜 '예'를 주는 것일까요?

yes와 no 대신 date와 NULL을 사용하고 싶습니다.

MySQL JSON 기능은 저에게 매우 새로운 기능입니다.그래서 누군가가 나에게 올바른 방향을 알려줄 수 있을까요?

시도:

옵션 1:

SELECT
  JSON_UNQUOTE(
    JSON_EXTRACT(
      `json`,
      REPLACE(
        JSON_UNQUOTE(
          JSON_SEARCH(
            `json`,
            'one',
            4,
            NULL,
            '$.order.dates[*].typeId'
          )
        ),
        'typeId',
        'date'
      )
    )
  ) `date`;

옵션 2:

SELECT
  IF(
    JSON_CONTAINS(
      JSON_EXTRACT(
        `json`,
        '$.order.dates[*].typeId'
      ),
      4
    ),
    'yes',
    'no'
  ) `exists`;

dbfidle을 참조하십시오.

다음 솔루션은 MySQL 8에서 작동합니다.

그것은 테이블을 가정합니다.my_table종대로jsonData이는 다음과 같습니다.

{
    "dates": [
        {
            "type": "created",
            "dt": "2021-10-10"
        },
        {
            "type": "updated",
            "dt": "2021-10-11"
        },
    ]
}

TL;DR SQL:

SELECT 
  JSON_EXTRACT(
        JSON_EXTRACT(
            jsondata,
            '$.dates[*].dt'
        ),
        JSON_UNQUOTE(
            JSON_SEARCH(
                JSON_EXTRACT(
                        jsonData,
                        '$.dates[*].type'
                    ),
                'one',
                'updated' -- the date field to load
            )
        )
  ) as dateUpdated
from my_table

여기 그것을 위한 효과적인 해결책이 있습니다.

SELECT
    
    -- The first step is to extract all the date types as an array 
    JSON_EXTRACT(
            jsonData,
            '$.dates[*].type'
    ) as jsonDateTypesAsArray,
    
    -- We can get a companion array of values, where the position within the array is the same as the types array above
    JSON_EXTRACT(
            jsonData,
            '$.dates[*].dt'
        ) as jsonDateValuesAsArray,
        
    -- Next, we search the types array for the first date type     
    JSON_UNQUOTE(
        JSON_SEARCH(                        
            JSON_EXTRACT(                   -- This is jsonDateTypesAsArray above
                    jsonData,
                    '$.dates[*].type'
                ),
            'one',
            'updated'                       -- This is the date field to load
            )
        ) as jsonLocalPathOfMatchingDate,

    -- Now we can call JSON_EXTRACT on the payload to get the path in jsonLocalPathOfMatchingDate
    JSON_UNQUOTE(
      JSON_EXTRACT(
        JSON_EXTRACT(                     -- This is jsonDateValuesAsArray above
            jsonData,
            '$.dates[*].dt'
        ),
        JSON_UNQUOTE(                     -- This is jsonLocalPathOfMatchingDate above 
            JSON_SEARCH(
                JSON_EXTRACT(
                        jsonData,
                        '$.dates[*].type'
                    ),
                'one',
                'updated.'                -- Date field to load
            )
        )
      )
    ) as dateUpdated
from my_table

언급URL : https://stackoverflow.com/questions/56240310/mysql-json-finding-value-of-sibling-element-in-sub-array