SQL Server FOR JSON: запрос списка значений и использование первых двух символов в качестве ключа в объекте json - PullRequest
2 голосов
/ 23 апреля 2019

У меня есть таблица с 900 000 строк. Один из столбцов имеет 7-символьное значение, которое мне нужно для поиска клиентской проверки ввода пользователя. В настоящее время я использую ajax в качестве пользовательских типов, но большинство пользователей могут обойти Ajax-циклы и заканчивать тем, что вынуждены ждать, пока все вызовы проверки не вернутся. Поэтому я хочу перенести время ожидания на начальную загрузку приложения и использовать преимущества кэширования в браузере. Так что я буду связывать минимизировать и сжать файл JSON с веб-пакетом. Я, вероятно, сделаю запись, которую затем смогу требовать / проверять при загрузке приложения.

Чтобы сделать проверку очень быстрой на стороне клиента, я хочу создать файл json, который имеет одну структуру json с первыми двумя символами 7-символьного столбца в качестве ключа к объекту с массивом всех значений, которые начинаются с первыми двумя символами в виде массива в значении для указанного ключа (см. пример ниже). Затем я могу использовать indexOf, чтобы найти значение в этом сегментированном списке, и это будет очень быстро.

Как уже упоминалось выше, в настоящее время я использую ajax в качестве пользовательских типов.

Я не собираюсь показывать свой код, потому что он слишком сложный. Но я в основном отслеживаю ожидающие ajax-запросы, и когда возвращается запрос, который начался с последнего введенного пользователем значения (значение, которое в данный момент находится в текстовом поле), тогда я могу показать пользователю, существует запись или нет. Таким образом, если запрос возвращается не по порядку, я не даю ложных срабатываний.

Я использую SQL Server 2016, поэтому я хочу использовать for json для получения желаемого результата. Но вот что я хочу произвести:

{
    "00": [ "0000001", "0000002", ... ],
    "10": [ "1000000", "1000001", ... ],
    //...
    "99": [ "9900000", "9900001", ...]
}

До сих пор я не мог понять, как использовать substring( mySevenDigitCol, 1, 2 ) в качестве ключа в объекте json.

1 Ответ

2 голосов
/ 24 апреля 2019

Я не уверен, что это можно сделать с помощью FOR JSON AUTO (["0000001", "0000002", ... ] - сложная часть), но следующий подход, основанный на манипуляции со строками, является одним из возможных решений вашей проблемы:

Введите:

CREATE TABLE #Data (
   SevenDigitColumn varchar(7)
)
INSERT INTO #Data
   (SevenDigitColumn)
VALUES
   ('0000001'),
   ('0000002'),
   ('0000003'),
   ('0000004'),
   ('0000005'),
   ('1000001'),
   ('1000002'),
   ('9900001'),
   ('9900002')

T-SQL:

;WITH JsonData AS (
   SELECT 
      SUBSTRING(dat.SevenDigitColumn, 1, 2) AS [Key],
      agg.StringAgg AS [Values]
   FROM #Data dat
   CROSS APPLY (
      SELECT STUFF(
         (
         SELECT CONCAT(',"', SevenDigitColumn, '"')
         FROM #Data
         WHERE SUBSTRING(SevenDigitColumn, 1, 2) = SUBSTRING(dat.SevenDigitColumn, 1, 2)
         FOR XML PATH('')
         ), 1, 1, '') AS StringAgg
      ) agg
   GROUP BY SUBSTRING(dat.SevenDigitColumn, 1, 2), agg.StringAgg
)

SELECT CONCAT(
   '{',
   STUFF(
      (
      SELECT CONCAT(',"', [Key], '": [', [Values], ']')
      FROM JsonData
      FOR XML PATH('')
      ), 1,  1, ''),
   '}')   

Выход:

{"00": ["0000001","0000002","0000003","0000004","0000005"],"10": ["1000001","1000002"],"99": ["9900001","9900002"]}

Примечания: В SQL Server 2017+ вы можете использовать функцию STRING_AGG () :

SELECT 
   CONCAT(
      '{',
      STRING_AGG(KeyValue, ','),
      '}'
   )
FROM (   
   SELECT CONCAT(
      '"',
      SUBSTRING(dat.SevenDigitColumn, 1, 2),
      '": [',
      STRING_AGG('"' + SevenDigitColumn + '"', ','),
      ']'
   ) AS KeyValue  
   FROM #Data dat
   GROUP BY SUBSTRING(dat.SevenDigitColumn, 1, 2)
) JsonData

Примечания:

Если данные вашего столбца не только цифры, вы должны использовать STRING_ESCAPE () с 'json' в качестве второго параметра для экранирования специальных символов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...