Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak podzielić zawartość komórki i wyodrębnić informacje do nowej kolumny w instrukcji SQL select?

Odpowiedziałem już dzisiaj na niesamowicie podobne pytanie, więc spójrz na odpowiedź:

SQL oddzielony przecinkami kolumna => do wierszy, a następnie suma sum?

ale spróbuj tego:

Wolę podejście oparte na tabeli liczb do dzielenia ciągu w TSQL

Aby ta metoda działała, musisz wykonać tę jednorazową konfigurację harmonogramu:

SELECT TOP 10000 IDENTITY(int,1,1) AS Number
    INTO Numbers
    FROM sys.objects s1
    CROSS JOIN sys.objects s2
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)

Po skonfigurowaniu tabeli liczb utwórz tę funkcję podziału:

CREATE FUNCTION [dbo].[FN_ListToTable]
(
     @SplitOn  char(1)      --REQUIRED, the character to split the @List string on
    ,@List     varchar(8000)--REQUIRED, the list to split apart
)
RETURNS TABLE
AS
RETURN 
(

    ----------------
    --SINGLE QUERY-- --this will not return empty rows
    ----------------
    SELECT
        ListValue
        FROM (SELECT
                  LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue
                  FROM (
                           SELECT @SplitOn + @List + @SplitOn AS List2
                       ) AS dt
                      INNER JOIN Numbers n ON n.Number < LEN(dt.List2)
                  WHERE SUBSTRING(List2, number, 1) = @SplitOn
             ) dt2
        WHERE ListValue IS NOT NULL AND ListValue!=''

);
GO 

Możesz teraz łatwo podzielić ciąg CSV na tabelę i dołączyć do niego:

select * from dbo.FN_ListToTable(',','1,2,3,,,4,5,6777,,,')

WYJŚCIE:

ListValue
-----------------------
1
2
3
4
5
6777

(6 row(s) affected)

Teraz możesz użyć KRZYŻA ZASTOSUJ, aby podzielić każdy wiersz w tabeli, tak jak:

DECLARE @YourTable table (RowID int, RowValue varchar(200))
INSERT INTO @YourTable VALUES (1,'KEY11:VALUE11;KEY12:VALUE12;KEY13:VALUE13')
INSERT INTO @YourTable VALUES (2,'KEY21:VALUE21;KEY22:VALUE22;KEY23:VALUE23')
INSERT INTO @YourTable VALUES (3,'KEY31:VALUE31;KEY32:VALUE32;KEY33:VALUE33')


SELECT
    o.RowID,RIGHT(st.ListValue,LEN(st.ListValue)-CHARINDEX(':',st.ListValue)) AS RowValue
    FROM @YourTable  o
        CROSS APPLY  dbo.FN_ListToTable(';',o.RowValue) AS st

WYJŚCIE:

RowID       
----------- -------
1           VALUE11
1           VALUE12
1           VALUE13
2           VALUE21
2           VALUE22
2           VALUE23
3           VALUE31
3           VALUE32
3           VALUE33

(9 row(s) affected)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak odwrócić słowa w kolumnie

  2. Jak najlepiej wybrać minimalną wartość z kilku kolumn?

  3. sp_MSforeachdb:uwzględniaj tylko wyniki z baz danych z wynikami

  4. SQL Server sprawdza rozróżnianie wielkości liter?

  5. odzyskać miejsce po przeniesieniu indeksów do grupy plików