Member 12300036 Ответов: 2

Как удалить косую черту между двумя значениями в столбце таблицы в SQL


у меня есть таблица, в которой данные поступают следующим образом:
привод суммы claimid
1 10/11 автомобиль/велосипед
2 11 автомобиль

я хочу показать данные о пользовательском интерфейсе на основе идентификатора претензии: если есть какая-то косая черта, то удалите ее:
claimid  amount     drive 
1          10        car
           11        bike     
             
2          11        car


Что я уже пробовал:

я не знаю, как это реализовать, так как никогда не сталкивался с таким состоянием

[no name]

Что такое "Слейс"?

Member 12300036

косая черта*

Richard Deeming

Звучит как невероятно плохой дизайн базы данных. Несколько полей в одном столбце - это всегда плохая идея.

Вы должны нормализовать свою базу данных - вам нужно как минимум две таблицы:

Claims (claimid : primary key)
ClaimDetails (claimid : foreign key, amount, drive)

Тогда ваши данные станут:
Claims:
=======
claimid
-------
1
2

ClaimDetails
============
claimid  amount  drive
----------------------
1        10      car
1        11      bike
2        11      car

что уже довольно близко к желаемому результату.

2 Ответов

Рейтинг:
2

The14thNoah

Привет,

основываясь на моем понимании вашего вопроса, Вы можете попробовать этот фрагмент для удаления обратной косой черты между данными вашего столбца

SELECT CASE
         WHEN ColumnName LIKE '%/%' THEN LEFT(ColumnName, Charindex('/', ColumnName) - 1)
         ELSE ColumnName
       END


CHill60

Но если колонка amountсодержит '10/11' и столбец drive содержит "автомобиль/велосипед", как получает ОП
1 10 автомобилей
1 11 велосипед
с помощью этого метода?

The14thNoah

можете ли вы дать мне образцы данных из вашей таблицы? и образец запроса тоже?

CHill60

Я не оперативник. ОП предоставила некоторые примерные данные и ожидаемые результаты в своем вопросе.

Member 12300036

уже опишите все, о чем идет речь

Рейтинг:
0

CHill60

Вы можете разделить строку в SQL на основе этого символа. Есть несколько способов сделать это. Этот используется для XML ... Разделение строк с разделителями с помощью XML в SQL Server[^]
И этот (который я использую) на самом деле использует цикл WHILE (но никому не говорите!)... Как разбить строку на символ с разделителями в SQL Server.............. - SQLServerCentral[^]
Тогда возникает проблема, как объединить данные так, как вы хотите. Я закончил с этим действительно ужасным запросом

declare @tab table (claimid int, amount nvarchar(50), drive nvarchar(50))
declare @inc int = 1
declare @top int = (SELECT MAX(claimid) FROM ClaimDetails) 
WHILE @inc <= @top
BEGIN
	declare @amt nvarchar(50), @drv nvarchar(50)
	SELECT @amt = amount, @drv = drive FROM ClaimDetails WHERE claimid = @inc

	declare @tab1 table (rn int identity(1,1), claimid int, amount nvarchar(50))
	declare @tab2 table (rn int identity(1,1), claimid int, drive nvarchar(50))

	INSERT INTO @tab1 SELECT @inc, splitdata as amount FROM dbo.fnSplitString(@amt, '/') 
	INSERT INTO @tab2 SELECT @inc, splitdata as amount FROM dbo.fnSplitString(@drv, '/') 

	INSERT INTO @tab
	SELECT @inc, amount, drive
	FROM @tab1 T1
	LEFT JOIN @tab2 T2 ON T1.claimid=T2.claimid AND T1.rn=T2.rn

	delete @tab1
	delete @tab2

	SET @inc += 1
END 

SELECT * FROM @tab

Он получает желаемые результаты, но я думаю, что этот процесс лучше оставить на вашем уровне пользовательского интерфейса, если это вообще возможно

[ОБНОВЛЕНИЕ]
Как и было запрошено, вот пошаговое объяснение этого запроса

Я объявил переменную таблицы @tab провести окончательные результаты. Он должен быть идентичен по форме вашей таблице ClaimDetails.

Далее идут переменные @inc(сокращение от "инкремент") и @top (сокращение от "максимальная заявленная стоимость"). Пока я писал это объяснение, я понял, что у меня есть @top = COUNT... но я должен читать максимальное значение - я исправил код выше. Эти переменные просто управляют циклом WHILE, который будет проходить через всю таблицу ClaimDetails строка за строкой (циклы обычно не нужны, но ваши требования несколько уникальны).

Внутри этого цикла мы получаем некоторую информацию из каждой строки, по одному ряду за раз.. Итак, первый раз через петлю проходит линия
SELECT @amt = amount, @drv = drive FROM ClaimDetails WHERE claimid = @inc
возвращает строку для claimid = 1 и устанавливает переменную @amt к значению 10/11 и @drv к значению car/bike.

Затем мы можем передать эти значения в функцию разделения строк из ссылки, которую я включил выше. Я не собираюсь объяснять это так, как это делает сам автор. Главное, что мы не можем сделать это в SELECT оператор непосредственно потому, что функция возвращает a стол результатов

Табличная переменная @tab1 и @tab2 будет содержать результаты разбиения этих строк. То rn колонка на каждой автоматически назначит "номер строки", который мы будем использовать позже, чтобы сопоставить " 10 " с "автомобилем" и " 11 " с "велосипедом".

Итак, после первого цикла @tab1 содержит
rn   claimid  amount
1    1        10
2    1        11
и @tab2 содержит
rn   claimid  drive
1    1        car
2    1        bike
Следующий бит берет эти две таблицы и сопоставляет rn = 1 на @tab1 (значение '10') с rn = 1 на @tab2 (значение 'автомобиль'), а затем rn = 2 (значение '11') с rn = 2 на @tab2 (значение 'велосипед'). Честно говоря, на самом деле вам это и не нужно. T1.claimid=T2.claimid потому что мы находимся в цикле, и единственные данные, которые у нас есть, - это один claimid для каждой итерации цикла.

Итак, после первого цикла @tab содержит
claimid amount  drive
1	10	car
1	11	bike
Вы должны удалить содержимое переменных таблицы для каждого цикла, иначе данные будут удвоены-даже если переменные объявлены внутри цикла!

Очевидно, не забудьте включить счетчик циклов
SET @inc += 1
чтобы избежать бесконечного цикла. Эта линия такая же, как
SET @inc = @inc + 1
Когда цикл будет завершен переменная таблицы @tab содержит разделение данных так, как вы описали в своем посте
claimid  amount     drive 
1          10        car
1          11        bike     
             
2          11        car
Обратите внимание, что вторая строка также содержит claimid 1 Вы не можете вернуть результаты точно так, как вы описали в своем посте, вы определенно должны справиться с этим на уровне пользовательского интерфейса.


Member 12300036

как это работает..это не постоянное решение

CHill60

Я не понимаю этого комментария.
Я также не понимаю, почему вы приняли решение, которое не дает результатов, о которых вы просили

Member 12300036

есть ли другое решение для этого?

CHill60

Если вы хотите, чтобы это было в SQL, то вышеизложенное-единственный способ, который я мог придумать. Я уже предложил сделать это на уровне пользовательского интерфейса, и Ричард Диминг предложил способ улучшить вашу базу данных. Возможно, есть и другое решение, но я не могу его придумать.
Ранее вы сказали: "как это работает...это не постоянное решение" - что вы имели в виду? Хотите получить объяснение, как это работает?

Member 12300036

дааа