1

有没有办法对字符串的一部分进行分组....

我想创建一个 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 by 但效果与不使用 group by 相同 ^^

我能做些什么来实现这一目标?

像这样解决:

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具有与 a 相同的效果GROUP BY

+1如果扫描找不到任何东西,则用于获取 0。如果没有找到它实际上返回-1。但 IF 需要 0(假)或 1+(真)。在我的情况下,永远不会有-第一名。

无法使用 GROUP BY,因为它只接受整数或列。

4

4 回答 4

2

你可以试试这个,它会找出破折号的位置并正确分组

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
于 2015-03-06T11:05:38.973 回答
1

为了分组,您必须指定要分组的字符串的哪一位。在这种情况下,它是前 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

唯一可能出现问题的是,如果您的 ID 开始大于 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 语言参考

于 2015-03-06T11:03:27.900 回答
0

如果您不关心另一列,则意味着在这种情况下,分组依据将从其他列中选择随机值,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 ;
于 2015-03-06T11:09:29.753 回答
0

我相信 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
于 2015-03-06T11:33:45.170 回答