• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

SQL - zliczanie rekordów z niedozwolonymi znakami.

VPS Starter Arubacloud
0 głosów
754 wizyt
pytanie zadane 6 sierpnia 2018 w SQL, bazy danych przez Starkov Nowicjusz (140 p.)

Witam, 

mam pewien problem z którym nie mogą sobie poradzić. Mam dwie tabele: Contractors i Chars

W pierwszej znajduje się kolumna Name z ciągiem znaków będącym nazwą firmy. Rekordów jest kilkadziesiąt tysięcy.

W drugiej znajdują się dwie kolumny: Char i Allowed. W pierwszej znajduje się 90 wierszy wypełnionych różnymi pojedynczymi znakami (np. A, B, 0, %, ?, <, /), a w drugiej wartości 1 lub 0 (określają czy znak dozwolony lub niedozwolony). Musze przelecieć przez każdy rekord z tabeli Contactors z kolumny Name i sprawdzić w ilu znajduje się choć jeden znak z tabli Chars z wartością 0 (czyli policzyć w ilu nazwach firm znajduje się choć jeden niedozwolony znak).

Problem jest taki, że nie wiem nawet jak to za bardzo ugryźć, w SQL pisałem dotąd jedynie proste selecty i procedurki, rozumiem tylko że trzeba by rozbić każdy string na pojedyncze znaki ale nie wiem jakich do tego mechanizmów i funkcji SQLa użyć. Próbowałem z kursorami bo jest tam możliwość przetwarzania rekord po rekordzie i może coś w ten sposób (nie udało się), a może lepiej jakaś procedurę? Czy ktoś mógłby mnie naprowadzić na dobry trop i powiedzieć jak on by do tego podszedł? 

 

komentarz 7 sierpnia 2018 przez adrian17 Ekspert (344,100 p.)
(inna sprawa, że to jakiś strasznie dziwny system, wygląda jak jakieś przekombinowane zadanie domowe)
komentarz 30 sierpnia 2018 przez ukasz112 Początkujący (390 p.)

Zgodzę się. Nie idzie tego optymalnie rozwiązać. Albo kursor albo sprawdzenie literka po literce, albo cross join albo jakieś pętle. Ogólnie rozwiązania nie sqlowe.

 

Zaproponowałbym zakorzystanie z PATINDEX() w przypadku T-SQL

 

SELECT
--	name,
--	PATINDEX('%[ĘŁ<>Ą]%',name) ,
	CASE 
		WHEN PATINDEX('%[ĘŁ<>Ą]%',name) = 0 THEN 'Dozwolone'
		WHEN PATINDEX('%[ĘŁ<>Ą]%',name) != 0THEN 'Niezodwolone' 
		ELSE null
	END AS Allowed,
		COUNT(*)
FROM contractors
GROUP BY 
	CASE 
		WHEN PATINDEX('%[ĘŁ<>Ą]%',name) = 0 THEN 'Dozwolone'
		WHEN PATINDEX('%[ĘŁ<>Ą]%',name) != 0THEN 'Niezodwolone' 
		ELSE null
	END 

 

 

komentarz 30 sierpnia 2018 przez ukasz112 Początkujący (390 p.)

Wymyśliłem! :)

 

create table contractors (id int identity(1,1), Name varchar(200))

insert into contractors(name) values ('Nazwa 1 ĄĘ')
insert into contractors(name) values ('Nazwa 2')
insert into contractors(name) values ('Nazwa 1 65')

create table chars (char char(1), allowed bit)
insert into chars(char, allowed)('6',0)
insert into chars(char, allowed)('Ą',0)
insert into chars(char, allowed)('Ę',0)

DECLARE @char varchar(max) = '';
SELECT @char += c.chars from chars c
SELECT  @char


SELECT
--	name,
--	PATINDEX('%'+@char+'%',name) ,
	CASE 
		WHEN PATINDEX('%'+@char+'%',name) = 0 THEN 'Dozwolone'
		WHEN PATINDEX('%'+@char+'%',name) != 0 THEN 'Niezodwolone' 
		ELSE null
	END AS Allowed,
		COUNT(*)
FROM contractors
GROUP BY 
	CASE 
		WHEN PATINDEX('%'+@char+'%',name) = 0 THEN 'Dozwolone'
		WHEN PATINDEX('%'+@char+'%',name) != 0 THEN 'Niezodwolone' 
		ELSE null
	END

 

2 odpowiedzi

0 głosów
odpowiedź 7 sierpnia 2018 przez areklipno Stary wyjadacz (11,930 p.)

poniżej napisałem Ci kod, który rozkłada wyrazy na litery

with slowa as (
select 'arek' as slowo
union all select 'szczebrzeszyn'
), litery as (
select substring(slowo,1,1) znaki
	,stuff(slowo,1,1,'') slowo
	,slowo wyraz
	, 1 as idw
from slowa

union all
	select substring(slowo,1,1) znaki
	,stuff(slowo,1,1,'') slowo
	, wyraz
	, idw+1 as idw
from litery
where len(slowo) > 0

)

select * 
from litery
order by wyraz

wystarczy teraz że zamiast tabeli słowa użyjesz swojej contractors, a tabele litery połączysz joinem z Twoją tabelą chars

0 głosów
odpowiedź 10 sierpnia 2018 przez Catalonya1992 Mądrala (5,440 p.)

Byłeś na dobrym tropie z tym kursorem. Tworzysz kursor select * from contractors. Później w pętli sprawdzasz dla każdej firmy czy ma znak niedozwolony, tzn.możesz stworzyć pętlę wewnętrzną (może być kursor select * from chars where allowed = '0');

W pętli wewnętrznej sprawdzasz czy nazwa firmy like '%'niedowzolony_znak_z_petli'%'. Jeśli tak to insert do jakiej tabeli i tam będzie lista tych błędnych nazw.

Kod:

declare

--lista wszystkich firm
cursor contractors is select * from contractors;

--lista niedozwolonych znaków
cursor chars is select * from chars where allowed = '0';

begin
    --pętla zewnętrzna
    for i in contractors
    loop
         --pętla wewnętrzna
        for x in chars
        loop
            --jesli nazwa ma niedozowlony znak
            if i.nazwa_firmy like '%'||x.char||'%' then
                insert into nowa_tabela values (i.nazwa_firmy);
                
                --zatwierdzenie inserta
                 commit;
            end if;
        --tu mozesz dodac tez sekcje obsługi wyjątków, żeby wiedziec jak wystapi jakis bład
        end loop;

    end loop;
    
end;

Daj znać czy zadziałało.

 

Podobne pytania

0 głosów
0 odpowiedzi 298 wizyt
pytanie zadane 17 marca 2019 w PHP przez Aleksander Kowalski Obywatel (1,510 p.)
0 głosów
0 odpowiedzi 94 wizyt
pytanie zadane 1 listopada 2020 w SQL, bazy danych przez blowing_rocket Nowicjusz (170 p.)
0 głosów
2 odpowiedzi 269 wizyt
pytanie zadane 23 marca 2023 w SQL, bazy danych przez XDBX Użytkownik (640 p.)

92,452 zapytań

141,262 odpowiedzi

319,085 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...