SQL Select GROUP BY часть поля, если имеет специальный символ

Есть ли способ GROUP BY части строки....

Я хотел создать SQLFIDDLE, но они, похоже, имеют проблемы с сервером, поэтому я должен сделать его видимым здесь....

Это были бы данные...

CREATE TABLE tblArticle
    (
     id int auto_increment primary key, 
     art_id varchar(20), 
     art_name varchar(30),
     art_color varchar(30),
     art_type varchar(5)
    );

INSERT INTO tblArticle
(art_id, art_name, art_color, art_type)
VALUES
('12345-1','Textile', 'Black','MAT'),
('12345-2','Textile', 'Red','MAT'),
('12345-3','Textile', 'Green','MAT'),
('12345-4','Textile', 'Blue','MAT'),
('54321-1','Textile', 'Black','MAT'),
('54321-2','Textile', 'Red','MAT'),
('54321-3','Textile', 'Green','MAT'),
('54321-4','Textile', 'Blue','MAT');

Итак, я получаю что-то вроде:

| id        | art_id   | art_name | art_color | art_type |
----------------------------------------------------------
| 1         | 12345-1  | Textile  | Black     | MAT      |
| 2         | 12345-2  | Textile  | Red       | MAT      |
| 3         | 12345-3  | Textile  | Green     | MAT      |
| 4         | 12345-4  | Textile  | Blue      | MAT      |
| 5         | 54321-1  | Textile  | Black     | MAT      |
| 6         | 54321-2  | Textile  | Red       | MAT      |
| 7         | 54321-3  | Textile  | Green     | MAT      |
| 8         | 54321-4  | Textile  | Blue      | MAT      |
| 9         | 9876543  | Textile  | White     | MAT      |
----------------------------------------------------------

Мой выбор выглядит как

Select art_id, art_name FROM tblArticle WHERE art_type = 'MAT' GROUP BY art_name

Что мне нужно, это art_id (не имеет значения, если его с -1 или -2 и так далее) и art_name для дальнейших запросов.

Как видите, у меня есть 2 разные группы art_id... и я хочу сгруппировать их.

Итак, я получаю две группы... 12345 и 54321. Но я даже не знаю, с чего начать ^^

Ожидаемый результат:

12345,   Textile
54321,   Textile
9876543, Textile

Я пытался добавить art_id в мою группу, но эффект тот же, что и не использовать group ^^

Что я мог сделать, чтобы достичь этого?

Решено как:

SELECT DISTINCT @IF( @SCAN( art_id, '-' ) +1, 
                     @LEFT( art_id, @SCAN( art_id, '-')),
                     art_id) AS art_id, art_name
FROM                 tblArticle
WHERE                art_type LIKE '%MAT%';

В этом случае DISTINCT имеет такой же эффект, как GROUP BY,

+1 используется для получения 0, если сканирование не может найти ничего. На самом деле он возвращает -1, если не был найден. Но если требуется 0 (false) или 1+ (true). И никогда не будет - на первом месте в моем случае.

Не удалось использовать GROUP BY, потому что он принимает только целое число или столбец.

4 ответа

Решение

Чтобы сгруппировать, вы должны указать, по какому биту строки группировать. В данном случае это первые 5 символов, поэтому вы должны использовать LEFT(art_id,5), Это должно соответствовать в SELECT заявление, так что вам нужно будет изменить его, чтобы прочитать то же самое. Я присвоил этому столбцу псевдоним art_id, иначе он будет неизвестен:

SELECT       LEFT(art_id,5) AS art_id, art_name 
FROM         tblArticle 
WHERE        art_type = 'MAT' 
GROUP BY     LEFT(art_id,5), art_name

Единственное, что может быть проблемой, это если вы начинаете иметь идентификаторы больше 5 символов. В этом случае вам нужно будет использовать @FIND чтобы найти черту и повернуть налево от этого. Это будет сбой, если нет черты, как @FIND Функция возвращает -1, если совпадений не найдено, поэтому мы должны использовать @IF заявление, чтобы компенсировать это.

В этом случае я бы написал:

SELECT       @IF(art_id LIKE '%-%'
                 ,@LEFT(art_id, @FIND('-', art_id, 0) - 1)
                 ,art_id
                 ) AS art_id, art_name 
FROM         tblArticle 
WHERE        art_type = 'MAT' 
GROUP BY     @IF(art_id LIKE '%-%'
                 ,@LEFT(art_id, @FIND('-', art_id, 0) - 1)
                 ,art_id
                 ), art_name

Символы @ необходимы (по крайней мере, я так думаю, попробуйте без, если они не работают), я раньше не использовал SQLBase, поэтому я использую следующую официальную документацию в качестве руководства:

GUPTA SQLBase - Справочник по языку SQL

Вы можете попробовать это, это сработает, где тире и сгруппированы должным образом

Select case when Instr(art_id, '-') = 0 
              then art_id 
              else Left(art_id, Instr(art_id, '-') - 1) end, art_name 
FROM tblArticle 
WHERE art_type = 'MAT' 
GROUP BY case when Instr(art_id, '-') = 0 
              then art_id 
              else Left(art_id, Instr(art_id, '-') - 1) end
,art_name

Если вас не волнует другой столбец, означающий, что группирование по выбору случайных значений из другого столбца, в этом случае art_name и это может быть случайным из одного из art_id Вы можете использовать как

select 
substring_index(art_id,'-',1) as atr_id_val , 
art_name 
from tblArticle 
where art_type = 'MAT'
group by atr_id_val ;

Если вам нужно выбрать все столбцы и убедиться, что все столбцы из последней записи number-{1 or 2} Вы можете использовать как

select 
t1.id,
substring_index(t1.art_id,'-',1) as art_id, 
t1.art_name , 
t1.art_color , 
t1.art_type from tblArticle t1 
left join tblArticle t2 on substring_index(t2.art_id,'-',1) = substring_index(t1.art_id,'-',1) and t1.id < t2.id and t1.art_type = 'MAT'  where t2.id is null ;

Обрезка art_id должна быть включена в select и я верю.

Select left( art_id, iif(CHARINDEX('-',art_id) > 0,CHARINDEX('-',art_id)-1, len(art_id) )) art_id, art_name 
    FROM tblArticle 
    WHERE art_type = 'MAT' 
    GROUP BY left ( art_id, iif(CHARINDEX('-',art_id) > 0,CHARINDEX('-',art_id)-1, len(art_id) ))
    ,art_name
Другие вопросы по тегам