Як рахувати екземпляри символів у колонці SQL


111

У мене стовпець sql, що є рядком із 100 символів "Y" або "N". Наприклад:

YYNYNYYNNYYNY ...

Який найпростіший спосіб отримати кількість усіх символів "Y" у кожному рядку.


1
Чи можете ви вказати платформу? MySQL, MSSQl, Oracle?
Вінсент Рамдані

Так - з Oracle, здається, вам потрібна довжина, а не
подовження

Відповіді:


96

У SQL сервері:

SELECT LEN(REPLACE(myColumn, 'N', '')) 
FROM ...

18
Просто майте на увазі, що якщо в рядку більше "N" або "Y", це може бути неточним. Дивіться рішення нікфа для більш надійного методу.
Том H

319

Цей фрагмент працює в певній ситуації, коли у вас булева інформація: він відповідає "скільки там немає"?

SELECT LEN(REPLACE(col, 'N', ''))

Якщо в іншій ситуації ви насправді намагалися підрахувати виникнення певного символу (наприклад, "Y") у будь-якій заданій рядку, скористайтеся цим:

SELECT LEN(col) - LEN(REPLACE(col, 'Y', ''))

32
Друга - найкраща відповідь тут. Всі інші покладаються на особливу ситуацію рядка, що містить лише два різних символи.
Стів Беннетт

5
Лише зауваження: у T-SQL вам потрібно використовувати LEN, а не LENGTH.
Лука

4
@nickf SQL функція len обрізає пробіли, тому якщо ви шукали, скільки вхідних просторів у рядку скажемо "Привіт", ви отримаєте 0. Найпростішим способом було б додати попередній символ до рядка і відрегулювати лін, як так. ВИБІРТЕ LEN (col + '~') - LEN (ЗАМІНА (col, 'Y', '') + '~')
domenicr

3
Якщо вас турбує пробіли, використовуйте замість нього функцію DATALENGTH.
StevenWhite

2
@StevenWhite DATALENGTH повертає кількість використаних байтів. Так NVARCHAR буде подвоєний.
domenicr

18

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

Це в моєму полі Смужки ...

Жовтий, жовтий, жовтий, жовтий, жовтий, жовтий, чорний, жовтий, жовтий, червоний, жовтий, жовтий, жовтий, чорний

  • 11 Жовтень
  • 2 Чорний
  • 1 Червоний
SELECT (LEN(Stripes) - LEN(REPLACE(Stripes, 'Red', ''))) / LEN('Red') 
  FROM t_Contacts

Це дуже розумний спосіб! Дякую
Thelt

13
DECLARE @StringToFind VARCHAR(100) = "Text To Count"

SELECT (LEN([Field To Search]) - LEN(REPLACE([Field To Search],@StringToFind,'')))/COALESCE(NULLIF(LEN(@StringToFind), 0), 1) --protect division from zero
FROM [Table To Search]

+1 Це посилює другу пропозицію від @nickf, щоб вона фактично повідомила вам кількість екземплярів рядка, навіть якщо рядок, яку ви шукаєте, більше 1 символу
Кевін Хаідт

@ domenicr змінив цю відповідь, і мою редакцію було відхилено. Поділ має бути за LEN(@StringToFind).
Джеймі Кітсон

Вибачте @jamiek Я надіслав виправлений код, але не знаю, чому вашу редакцію відхилено.
domenicr

@domenicr Ви повинні повернутися до оригінального коду, ваша редакція ускладнює код без жодної мети, @StringToFindніколи не буде порожнім або порожнім.
Джеймі Кітсон

@JamieKitson Я бачу інакше. Перевірка поділу на нуль - це принцип найкращих практик. Крім того, підрахунок кількості пробілів у Field To Searchотримав би ділення на нуль, оскільки Len(' ')повертає нуль.
domenicr





0

Спробуйте це. Він визначає ні. подій одного символу, а також підрядних входжень у основний рядок.

SELECT COUNT(DECODE(SUBSTR(UPPER(:main_string),rownum,LENGTH(:search_char)),UPPER(:search_char),1)) search_char_count
FROM DUAL
connect by rownum <= length(:main_string);

0

Якщо ви хочете порахувати кількість екземплярів рядків з більш ніж одним символом, ви можете використовувати попереднє рішення з регулярним виразом, або це рішення використовує STRING_SPLIT, яке, на мою думку, було введено в SQL Server 2016. Також вам знадобиться сумісність рівень 130 і вище.

ALTER DATABASE [database_name] SET COMPATIBILITY_LEVEL = 130

.

--some data
DECLARE @table TABLE (col varchar(500))
INSERT INTO @table SELECT 'whaCHAR(10)teverCHAR(10)whateverCHAR(10)'
INSERT INTO @table SELECT 'whaCHAR(10)teverwhateverCHAR(10)'
INSERT INTO @table SELECT 'whaCHAR(10)teverCHAR(10)whateverCHAR(10)~'

--string to find
DECLARE @string varchar(100) = 'CHAR(10)'

--select
SELECT 
    col
  , (SELECT COUNT(*) - 1 FROM STRING_SPLIT (REPLACE(REPLACE(col, '~', ''), 'CHAR(10)', '~'), '~')) AS 'NumberOfBreaks'
FROM @table

0

Друга відповідь, яку надав нікф, дуже розумна. Однак він працює лише для символьної довжини цільової підрядки 1 і ігнорує пробіли. Зокрема, у моїх даних було два провідні простори, які SQL корисно видаляє (я цього не знав), коли всі символи праворуч видалені. Що означало це

"Джон Сміт"

згенеровано 12, використовуючи метод Нікфа, тоді як:

"Джо Блоггз, Джон Сміт"

згенеровано 10 та

"Джо Блоггз, Джон Сміт, Джон Сміт"

Створено 20.

Тому я трохи змінив рішення на наступне, що працює для мене:

Select (len(replace(Sales_Reps,' ',''))- len(replace((replace(Sales_Reps, ' ','')),'JohnSmith','')))/9 as Count_JS

Я впевнений, що хтось може придумати кращий спосіб зробити це!


0

Ви також можете спробувати це

-- DECLARE field because your table type may be text
DECLARE @mmRxClaim nvarchar(MAX) 

-- Getting Value from table
SELECT top (1) @mmRxClaim = mRxClaim FROM RxClaim WHERE rxclaimid_PK =362

-- Main String Value
SELECT @mmRxClaim AS MainStringValue

-- Count Multiple Character for this number of space will be number of character
SELECT LEN(@mmRxClaim) - LEN(REPLACE(@mmRxClaim, 'GS', ' ')) AS CountMultipleCharacter

-- Count Single Character for this number of space will be one
SELECT LEN(@mmRxClaim) - LEN(REPLACE(@mmRxClaim, 'G', '')) AS CountSingleCharacter

Вихід:

введіть тут опис зображення


0

Нижче рішення допоможе з’ясувати відсутність символу, що присутній у рядку з обмеженням:

1) за допомогою SELECT LEN (ЗАМІНА (myColumn, 'N', '')), але обмеження та неправильний вихід у нижченаведеній умові:

ВИБІРТЕ ОБ'ЄКТ (ЗАМІНА ('YYNYNYYNNYYNY', 'N', ''));
--8 - Правильно

ВИБІРТЕ ОБ'ЄКТ (ЗАМІНА ('123a123a12', 'a', ''));
--8 - Неправильно

ВИБІРТЕ ОБ'ЄКТ (ЗАМІНА ('123a123a12', '1', ''));
--7 - Неправильно

2) Спробуйте нижче рішення для правильного виводу:

  • Створіть функцію, а також змініть відповідно до вимог.
  • І функцію дзвінка, як показано нижче

виберіть dbo.vj_count_char_from_string ('123a123a12', '2');
--2 - Правильно

виберіть dbo.vj_count_char_from_string ('123a123a12', 'a');
--2 - Правильно

-- ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      VIKRAM JAIN
-- Create date: 20 MARCH 2019
-- Description: Count char from string
-- =============================================
create FUNCTION vj_count_char_from_string
(
    @string nvarchar(500),
    @find_char char(1)  
)
RETURNS integer
AS
BEGIN
    -- Declare the return variable here
    DECLARE @total_char int; DECLARE @position INT;
    SET @total_char=0; set @position = 1;

    -- Add the T-SQL statements to compute the return value here
    if LEN(@string)>0
    BEGIN
        WHILE @position <= LEN(@string) -1
        BEGIN
            if SUBSTRING(@string, @position, 1) = @find_char
            BEGIN
                SET @total_char+= 1;
            END
            SET @position+= 1;
        END
    END;

    -- Return the result of the function
    RETURN @total_char;

END
GO

0

Якщо вам потрібно порахувати char у рядку з більш ніж двома видами символів, ви можете використовувати замість 'n' -якогось оператора або регулярного вираження символів прийняти потрібне вам char.

SELECT LEN(REPLACE(col, 'N', ''))

-1

Ось, що я використовував у Oracle SQL, щоб перевірити, чи передає хтось правильно відформатований номер телефону:

WHERE REPLACE(TRANSLATE('555-555-1212','0123456789-','00000000000'),'0','') IS NULL AND
LENGTH(REPLACE(TRANSLATE('555-555-1212','0123456789','0000000000'),'0','')) = 2

Перша частина перевіряє, чи є в телефонному номері лише номери та дефіс, а друга частина перевіряє, чи є у телефону лише дві дефіси.


Що це питання стосується номерів телефонів? Він також просить вирішити T-SQL ...
Бен

-1

наприклад, щоб обчислити кількість екземплярів символу (a) у стовпці SQL -> ім'я є ім'ям стовпця '' (а в doblequote порожнє, я замінюю на nocharecter @ '')

виберіть len (ім'я) - len (замінити (ім'я, 'a', '')) з TESTING

select len ​​('YYNYNYYNNYYNY') - len (замінити ('YYNYNYYNNNYYNY', 'y', ''))

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.