Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

SQL:Sắp xếp theo chuỗi con của các chữ cái và số hỗn hợp

Tôi đặt đây là một câu trả lời mới, vì nó không thực sự là một câu trả lời mà là sự so sánh giữa các phương pháp tiếp cận khác nhau:

Kết luận:

  • tất cả các phương pháp tiếp cận đều có quy mô khá tuyến tính, ngoại trừ XML
  • XML nhanh nhất với số lượng hàng nhỏ nhưng trở nên tồi tệ hơn với số lượng hàng cao

Tạo một kịch bản thử nghiệm

CREATE TABLE #tbl (ID INT IDENTITY,sortColumn VARCHAR(100));
INSERT INTO #tbl VALUES
 ('A-1')
,('A-10')
,('A-2')
,('A-3')
,('A-4')
,('A-5')
,('A-6')
,('A-7')
,('A-8')
,('A-9')
,('A-3a')
,('A-3b')
,('A-3c')
,('B-1')
,('B-10')
,('B-11')
,('B-12')
,('B-12a')
,('B-12b')
,('B-13')
,('B-2')
,('B-3')
,('B-4')
,('B-5')
,('B-6')
,('B-7')
,('B-8')
,('A-8a')
,('B-8')
,('B-9'); --30 rows
GO 1000  -- x 1.000 = 30.000 rows

Cách tiếp cận của Matt (được làm sạch đến mức cần thiết)

  • 46 giây trên 3 mio hàng
  • 4,5 giây trên 300.000 hàng
  • 1,3 giây trên 30.000 hàng
  • 0,7 giây trên 3.000 hàng

SELECT ID,sortColumn
FROM
    #tbl
ORDER BY
LEFT(sortColumn,CHARINDEX('-',sortColumn) -1)
,CAST((CASE
    WHEN ISNUMERIC(SUBSTRING(sortColumn,CHARINDEX('-',sortColumn) + 1,3)) = 1 THEN SUBSTRING(sortColumn,CHARINDEX('-',sortColumn) + 1,3)
    WHEN ISNUMERIC(SUBSTRING(sortColumn,CHARINDEX('-',sortColumn) + 1,2)) = 1 THEN SUBSTRING(sortColumn,CHARINDEX('-',sortColumn) + 1,2)
    WHEN ISNUMERIC(SUBSTRING(sortColumn,CHARINDEX('-',sortColumn) + 1,1)) = 1 THEN SUBSTRING(sortColumn,CHARINDEX('-',sortColumn) + 1,1)
    ELSE NULL
END) AS INT)
,RIGHT(sortColumn,
    LEN(sortColumn) - 
    LEN(LEFT(sortColumn,CHARINDEX('-',sortColumn) -1)) 
    - LEN(CASE
            WHEN ISNUMERIC(SUBSTRING(sortColumn,CHARINDEX('-',sortColumn) + 1,3)) = 1 THEN SUBSTRING(sortColumn,CHARINDEX('-',sortColumn) + 1,3)
            WHEN ISNUMERIC(SUBSTRING(sortColumn,CHARINDEX('-',sortColumn) + 1,2)) = 1 THEN SUBSTRING(sortColumn,CHARINDEX('-',sortColumn) + 1,2)
            WHEN ISNUMERIC(SUBSTRING(sortColumn,CHARINDEX('-',sortColumn) + 1,1)) = 1 THEN SUBSTRING(sortColumn,CHARINDEX('-',sortColumn) + 1,1)
            ELSE NULL
    END)
    - 1 --the '-'
),ID;

Tính toán từng bước trong CROSS APPLY sắp xếp, sắp xếp trên các cột được tính toán

  • 44 giây trên 3 mio hàng
  • 4,4 giây trên 300.000 hàng
  • 0,9 giây trên 30.000 hàng
  • 0,3 giây trên 3.000 hàng

SELECT ID,sortColumn
FROM #tbl
CROSS APPLY(SELECT CHARINDEX('-',sortColumn) AS posMinus) AS pos
CROSS APPLY(SELECT SUBSTRING(sortColumn,1,posMinus-1) AS part1
                  ,SUBSTRING(sortColumn,posMinus+1,1000) AS part2
            ) AS parts
CROSS APPLY(SELECT ISNUMERIC(part2) AS p2isnum) AS checknum
CROSS APPLY(SELECT CASE WHEN p2isnum=1 THEN '' ELSE RIGHT(part2,1) END AS part3
                  ,CASE WHEN p2isnum=1 THEN part2 ELSE SUBSTRING(part2,1,LEN(part2)-1) END AS part2New
           ) AS partsNew
ORDER BY part1,part2new,part3,ID;

Tính toán từng bước trong CROSS APPLY sắp xếp, sắp xếp theo chuỗi có đệm được nối

  • 42 giây trên 3 hàng mio
  • 4,2 giây trên 300.000 hàng
  • 0,7 giây trên 30.000 hàng
  • 0,4 ​​giây trên 3.000 hàng

SELECT ID,sortColumn
FROM #tbl
CROSS APPLY(SELECT CHARINDEX('-',sortColumn) AS posMinus) AS pos
CROSS APPLY(SELECT SUBSTRING(sortColumn,1,posMinus-1) AS part1
                  ,SUBSTRING(sortColumn,posMinus+1,1000) AS part2
            ) AS parts
ORDER BY RIGHT('.....' + part1,5) + RIGHT('.....' + part2,5 - ISNUMERIC(RIGHT(part2,1)))
        ,ID;

Tách bằng XML, sắp xếp theo chuỗi có đệm được nối

  • 67 giây trên 3 mio hàng
  • 6,2 giây trên 300.000 hàng
  • 0,7 giây trên 30.000 hàng
  • 0,3 giây trên 3.000 hàng

SELECT ID,sortColumn
FROM
(
    SELECT CAST('<r>' + REPLACE(sortColumn,'-','</r><r>') + '</r>' AS XML) AS SortColumnSplitted
          ,*
    FROM #tbl
) AS tbl
ORDER BY RIGHT('.....' + SortColumnSplitted.value('r[1]','varchar(max)'),5) + RIGHT('.....' + SortColumnSplitted.value('r[2]','varchar(max)'),5 - ISNUMERIC(RIGHT(SortColumnSplitted.value('r[2]','varchar(max)'),1)))
        ,ID;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Spatial polygon từ trong ra ngoài

  2. Tự động tăng chỉ mục cho Microsoft SQL Server 2008 R2

  3. Cách sử dụng SqlTransaction trong C #

  4. Tạo một bảng tạm thời dựa trên một bảng khác trong SQL Server

  5. Ngoại lệ 'Đầu vào được chỉ định không đại diện cho trường hợp địa lý hợp lệ' khi sử dụng SqlGeographyBuilder