Mam tę manipulację ciągiem

select product,
       CAST((LENGTH(currencies) - LENGTH(REPLACE(currencies, '*', ''))) / LENGTH('*') AS UNSIGNED) AS currencies_count
  from MY_TABLE

Liczyć "waluty" w jednym polu w tej tabeli

product       currencies
-----------   --------------
prod_name_1   *usd*cad*euro*
prod_name_2   *usd*cad*
prod_name_3   *usd*cad*euro*
prod_name_4   
prod_name_5   *usd*

Manipulacja ciągiem znaków zwraca „+1” na wszystkich wynikach (na przykład: prod_name_1, 4 waluty zamiast 3). Dzieje się tak, ponieważ zewnętrzny komponent przechowuje pola wyboru danych w ten niespójny sposób (*usd*cad*euro* zamiast *usd*cad*euro).

Chodzi o to, że nie mogę zmienić sposobu przechowywania tego komponentu. Czy istnieje sposób, aby policzyć dokładną liczbę walut w polu, ignorując ostatnią „pustą” wartość po ostatnim separatorze „*”? Jak mogę zmodyfikować manipulację ciągami?

Szalejąc, każda pomoc będzie bardzo, bardzo mile widziana!

2
DavidF 6 marzec 2012, 14:27

2 odpowiedzi

Najlepsza odpowiedź

Powyższe zapytanie nie liczy pustej części ciągu po końcowym *. Wcale tego nawet nie dzieli. Mówi po prostu, że:

*eur*usd*

Jest o 3 znaki dłuższy niż

eurusd

Myślę, że aby uzyskać poprawną wartość, powinieneś po prostu sprawdzić pustą wartość waluty, a jeśli ją znajdziesz, ustaw wynik na 0. W przeciwnym razie wynikiem jest liczba symboli * minus 1:

SELECT
    CASE WHEN LENGTH(Currencies) = 0 THEN CAST(0 AS UNSIGNED) 
        ELSE CAST((LENGTH(Currencies) - LENGTH(REPLACE(Currencies, '*', ''))) / LENGTH('*') AS UNSIGNED) - 1 END AS currencies_count
FROM MY_TABLE

Nie mam bazy danych mysql, aby to przetestować, ale powinno być OK.

1
Tobsey 6 marzec 2012, 14:50

Po prostu odejmij 1 od obliczonej wartości, jeśli jest większa niż 0.

CREATE FUNCTION CountCurrencies(s VARCHAR(255), delim VARCHAR(3)) 
RETURNS INT 
BEGIN 
  SET @n = (LENGTH(s) - LENGTH(REPLACE(s, delim, ''))) / LENGTH(delim);
  IF @n > 0 THEN 
    RETURN @n - 1; 
  ELSE 
    RETURN 0; 
END IF; 
END


SELECT product, CountCurrencies(currencies, '*') FROM my_table;

Ale to brzydki sposób, manipulowanie danymi wewnątrz kolumny. Powinieneś to rozłożyć.

0
Ali 6 marzec 2012, 15:19