mysql 테이블에 열 (varchar (255))이 있는데,이를 "word"라고 부를 수 있습니다. 이 열의 값을 문자열의 문자로 정렬하여 반환하는 선택 쿼리를 작성하는 방법은 무엇입니까?MySQL에서 문자열 문자 정렬
예를 들어, 레코드 중 하나에 "earth"라는 단어가 있으면 모든 행에 대해 "aehrt"등을 반환해야합니다. 단일 쿼리에서이를 수행 할 수있는 방법이 있습니까?
mysql 테이블에 열 (varchar (255))이 있는데,이를 "word"라고 부를 수 있습니다. 이 열의 값을 문자열의 문자로 정렬하여 반환하는 선택 쿼리를 작성하는 방법은 무엇입니까?MySQL에서 문자열 문자 정렬
예를 들어, 레코드 중 하나에 "earth"라는 단어가 있으면 모든 행에 대해 "aehrt"등을 반환해야합니다. 단일 쿼리에서이를 수행 할 수있는 방법이 있습니까?
매우 비효율적하지만, 사용자 정의 함수에 대한 필요없이 :
SELECT GROUP_CONCAT(LETTER SEPARATOR '') AS ReOrderedLetters
FROM (SELECT 'A' as LETTER FROM <table> WHERE UPPER(`name`) like '%A%'
UNION ALL
SELECT 'B' as LETTER FROM <table> WHERE UPPER(`name`) like '%B%'
UNION ALL
SELECT 'C' as LETTER FROM <table> WHERE UPPER(`name`) like '%C%'
UNION ALL
SELECT 'D' as LETTER FROM <table> WHERE UPPER(`name`) like '%D%'
...
UNION ALL
SELECT 'Y' as LETTER FROM <table> WHERE UPPER(`name`) like '%Y%'
UNION ALL
SELECT 'Z' as LETTER FROM <table> WHERE UPPER(`name`) like '%Z%'
) alpha
편집 내가 자기 전에 더 나은 대안을 마련했다
, 그렇지 않으면 내가 좋겠 절대 잠들지 않아. 그래서 여기에 훨씬 더 깨끗하고 효율적인 대안이 있습니다.
문자라는 VARCHAR (1)의 단일 열이있는 letters라는 테이블을 만들었습니다.
select U.`name`,
GROUP_CONCAT(L.`letter`
ORDER BY L.`letter` ASC
SEPARATOR '') AS ReOrderedLetters
FROM `users` U
LEFT JOIN `letters` L ON POSITION(L.`letter` IN UPPER(U.`name`)) > 0
GROUP BY U.`name`
우물 ... 나는 함수를 정의하고 싶습니다. –
@Vinko - 제 수정 된 솔루션이 더 깨끗해지기를 바랍니다. –
훨씬 좋아 졌어, 지금은 받아 들여진 대답처럼 보입니다. –
좋아 아이들 : 는 Z
다음CREATE TABLE IF NOT EXISTS `letters` (
`letter` varchar(1) NOT NULL,
PRIMARY KEY (`letter`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `letters` (`letter`) VALUES
('A'),('B'),('C'),('D'),('E'),('F'),('G'),('H'),('I'),('J'),('K'),('L'),('M'),
('N'),('O'),('P'),('Q'),('R'),('S'),('T'),('U'),('V'),('W'),('X'),('Y'),('Z');
에 문자 A를 해당 테이블을 채워집니다. 다음은 t-sql의 bubblesort 함수입니다. mysql으로 직접 변환 할 수있다. SQL Server가 실제로 재귀 함수를 좋아하지 않는다는 사실이 밝혀졌습니다. 그러나 실제로는 매우 빠르게 실행되었습니다.
Create Function bubblesort(@In varchar(255))
Returns varchar(255)
AS
BEGIN
Declare @Answer varchar(255)
Declare @swapped bit
Declare @Counter int
Set @Answer = @In;
--only need to sort strings longer than 1
if len(@Answer) > 1
BEGIN
While 1=1
BEGIN
Set @Counter = 1;
Set @swapped = 0;
While @Counter <= len(@Answer) - 1
BEGIN
If substring(@Answer, @Counter, 1) > substring(@Answer, @Counter + 1, 1)
BEGIN
--swap
Set @swapped = 1;
Set @Answer = Stuff(@Answer, @Counter, 2, reverse(substring(@Answer, @Counter, 2)));
END;
Set @Counter = @Counter + 1;
END;
if @swapped = 0
BREAK;
END;
END;
Return @Answer;
END;
go
결과
Select ltrim(myfield) from mytable;
그런 다음 각 임시 테이블로 각 단어의 문자와 GROUP_CONCAT()를 정렬을 s의 삽입을 손질하는 것을 잊지 마십시오. 이것은 아마도 커서의 사용과 모든 문자를 임시 테이블에 삽입하기 때문에 매우 효율적인 솔루션은 아닙니다. 나는 일종의 루틴이 더 빨라질 것이라고 내기는하지만 임시 테이블을 사용하지 않는다면 어떤 종류의 배열 구조가 필요하다. MySQL 프로 시저에 배열이 있는지 확실하지 않습니다.
delimiter $$
drop procedure if exists sort_letters$$
create procedure sort_letters()
begin
declare done int default 0;
declare word varchar(256);
declare cur1 cursor for select i from a;
declare continue handler for not found set done = 1;
drop temporary table if exists temp;
create temporary table temp (id int, letter char);
set @wordcount = 0;
open cur1;
repeat
fetch cur1 into word;
if not done then
set @counter = 0;
set @len = length(word);
while (@counter <= @len) do
insert into temp values
(@wordcount, substring(word,@counter,1));
set @counter = @counter + 1;
end while;
set @wordcount = @wordcount + 1;
end if;
until done end repeat;
close cur1;
select group_concat(letter order by letter separator '')
from temp group by id;
end$$
mysql> desc a;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| i | varchar(256) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
1 row in set (0.04 sec)
mysql> select * from a;
+-------+
| i |
+-------+
| earth |
| sand |
| fire |
+-------+
3 rows in set (0.00 sec)
mysql> call sort_letters();
+---------------------------------------------------+
| group_concat(letter order by letter separator '') |
+---------------------------------------------------+
| aehrt |
| adns |
| efir |
+---------------------------------------------------+
3 rows in set (0.00 sec)
각 문자를 한 번 나타내는 흥미로운 대안이 있습니다. 정확하게 확실하지 모든 문자를 표현하는 오버플로 오류의 일종을 유발하는 경우, 그러나 논리는 생각을위한 음식 :
분명히SELECT
CONCAT(
REPEAT('a',SIGN(POSITION('a' IN word_col))),
REPEAT('b',SIGN(POSITION('b' IN word_col))),
REPEAT('c',SIGN(POSITION('c' IN word_col))),
REPEAT('d',SIGN(POSITION('d' IN word_col))),
REPEAT('e',SIGN(POSITION('e' IN word_col))),
REPEAT('f',SIGN(POSITION('f' IN word_col))),
...
REPEAT('Z',SIGN(POSITION('Z' IN word_col)))
)
FROM
word
는 "종류"는 CONCAT 구성 방식을 기반으로합니다.
어떻게 복제본을 처리 하시겠습니까? "book"-> "bko"또는 "bkoo"? 관심이 없으면 왜이 작업을 수행해야합니까? –
대소 문자를 구별하지 않습니까? –
대소 문자를 구분하지 않습니다. –