Eu tenho uma tabela assim:
Eu ia | Observação | Cliente |
---|---|---|
1 | Nota longa com várias linhas Cliente: Nome |
nulo |
2 | Outra nota que tenha várias linhas Cliente: Nome |
nulo |
3 | Terceira nota que tem várias linhas Cliente: Linha de nome |
nulo |
4 | Linha: A Cliente: Linha de nome |
nulo |
5 | Linha B B: Linha Cliente: Nome linha outros |
nulo |
Quero extrair informações do cliente da coluna "Nota" para colocá-las na coluna "Cliente" com apenas uma consulta SQL.
Dei alguns exemplos que representam os milhares de linhas reais que tenho. Primeiro fiz esta consulta:
SELECT
CASE
WHEN posclient != 0 THEN SUBSTRING(
Note,
posclient + LENGTH('Client: '),
LOCATE('\n', Note, posclient + LENGTH('Client: ')) - (posclient + LENGTH('Client: '))
)
WHEN poscustomer != 0 THEN SUBSTRING(
Note,
poscustomer + LENGTH('Customer : '),
LOCATE('\n', Note, poscustomer + LENGTH('Customer : ')) - (poscustomer + LENGTH('Customer : '))
)
WHEN poscontact != 0 THEN SUBSTRING(
Note,
poscontact + LENGTH('Contact : '),
LOCATE('\n', Note, poscontact + LENGTH('Contact : ')) - (poscontact + LENGTH('Contact : '))
)
ELSE ''
END AS client,
Id
FROM (SELECT Id, Note,
LOCATE('Customer : ', Note) as poscustomer,
LOCATE('Client: ', Note) as posclient,
LOCATE('Contact : ', Note) as poscontact
FROM myTable) x
WHERE (poscustomer != 0 OR posclient != 0 OR poscontact != 0)
Como há código duplicado (a WHEN
parte), é difícil de ler e não fica muito bom se eu tiver outra maneira de adicionar.
E eu tenho: há pelo menos 6 maneiras de escrever o cliente. Quero otimizar esta parte:
WHEN poscontact != 0 THEN SUBSTRING(
Note,
poscontact + LENGTH('Contact : '),
LOCATE('\n', Note, poscontact + LENGTH('Contact : ')) - (poscontact + LENGTH('Contact : '))
)
Para ser "genérico", mas não sei como, pois não estou em linguagem de programação. Em php, isso seria fácil, mas não posso usar linguagem de programação, tenho que usar apenas uma consulta.
Uma coisa que pode ser muito útil: há apenas UMA maneira de escrever o cliente para cada linha. Ele sempre conterá apenas um.
Como posso fazer?
violino
De acordo com os valores fornecidos a consulta deve ser atualizada até
Se suas strings forem do estilo Windows, substitua o delimitador por
CONCAT(CHAR(13), CHAR(10))
.violino
Eu encontrei um jeito. Usando a função proposta por Akina:
SUBSTRING_INDEX
, há um jeito fácil: encontre a palavra-chave, então use-a como param.Fiddle de DB
A consulta:
Isso facilita a adição de uma nova maneira: basta adicionar
WHEN LOCATE (x, Note) != 0 THEN x
.