Sql-Server

僅使用 LIKE 運算符的大於紀元時間戳的記錄

  • June 26, 2022

到目前為止,我有以下查詢,不幸的是,我不能使用正則表達式大於運算符,我只能使用LIKE關鍵字。

整個列都在一個 json 字元串中,我不能使用json_value或正則表達式,因為我在 SQL Server 上,所以我堅持使用LIKE. 它是 SQL Server 2014,json_value直到 2016 年才受支持。

SELECT * FROM DataTableOne 
WHERE update_date LIKE '%1645290000%'

我想僅使用 SQLLIKE關鍵字(甚至使用 SQLLIKE運算符在 1645290000 和 9999999999 之間)檢索紀元 unix 時間戳大於 1645290000 的所有記錄。

任何幫助將不勝感激,因為這是一個非常艱難的獨特案例,我僅限於使用LIKE關鍵字。

範例表/數據如下:

CREATE TABLE DataTableOne (
   ID int,
   DATA varchar(MAX)
);

INSERT INTO DataTableOne (ID, DATA)
VALUES (1, '{"name":"Cole", "update_date":"2855290000"}'),
(2, '{"name":"Peter", "update_date":"1222290000"}') ;

這種數據可能有一千行,我唯一想要的是 update_date 大於 1645290000 的行。

在我給出的上表上執行查詢應該只返回第一行,因為 2855290000 的update_date在數值上確實大於 1645290000。

實際上,您不應該在沒有明確 JSON 支持的 SQL Server 版本中直接處理 JSON 數據。理想情況下,JSON 源將在導入期間轉換為關係格式。然後查詢數據變得容易。

也就是說,如果你真的必須按照你說的去做,有很多選擇。

一種是將(簡單)JSON 轉換為 XML,然後使用 XQuery:

SELECT
   DTO.*
FROM dbo.DataTableOne AS DTO
CROSS APPLY 
(
   SELECT 
       TRY_CONVERT(xml,
           REPLACE(
               REPLACE(
                   REPLACE(
                       REPLACE(DTO.[DATA], 
                           '"name":', 'name='),
                       ', "update_date":', ' update_date='),
                   '{', '<r '),
               '}', '/>'))
) AS X (x)
WHERE
   1 = X.x.exist('r[1][@update_date ge 1645290000]');

那裡沒有必要,但在每行只有一個update_date[1]的情況下會產生更好的執行計劃。

它也幾乎可以LIKE專門使用,但我不推薦它:

SELECT * 
FROM dbo.DataTableOne AS DTO
WHERE 
   DTO.[DATA] COLLATE Latin1_General_BIN2 
       LIKE '%"update_date":"164529[0-9][0-9][0-9][0-9]"%'
   OR DTO.[DATA] COLLATE Latin1_General_BIN2 
       LIKE '%"update_date":"1645[3-9][0-9][0-9][0-9][0-9][0-9]"%'
   OR DTO.[DATA] COLLATE Latin1_General_BIN2 
       LIKE '%"update_date":"164[6-9][0-9][0-9][0-9][0-9][0-9][0-9]"%'
   OR DTO.[DATA] COLLATE Latin1_General_BIN2 
       LIKE '%"update_date":"16[5-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"%'
   OR DTO.[DATA] COLLATE Latin1_General_BIN2 
       LIKE '%"update_date":"1[7-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"%'
   OR DTO.[DATA] COLLATE Latin1_General_BIN2 
       LIKE '%"update_date":"[2-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"%';

db<>fiddle線上展示

如果您了解那裡的LIKE邏輯,您將能夠將其推廣到其他值。如果您要嘗試解決難題或設置某種問題,那應該可以幫助您入門。

引用自:https://dba.stackexchange.com/questions/313750