MySQL如何GROUP_CONCAT特定字段?

发布于 2024-11-10 09:51:34 字数 4153 浏览 3 评论 0原文

我有一张包含本地化字符串的表和一张通过组合和引用表 Strings 中的 idString 来创建带有值的标签的表。在底部您可以找到一个 MySQL 脚本来创建所有这些数据。

字符串

idString  SE             EN
--------------------------------
3         Färg           Color
4         Svart          <null>
5         Röd            Red
6         Nokia          <null>
8         Mobiltelefon   Cell phone
9         Produkt märke  Brand
11        Typ            Type

TABLE: ItemData
idItem  idTag  idValue
--------------------------------
1       9      6      
1       3      5      
1       3      4      
1       11     8       

我发出此 SQL 语句(随意建议任何优化)来查找表字符串中的 idTag 和 idValue 并检索它们的文本值。

SELECT d.*,
       IFNULL(sTag.en,sTag.se) sTag,
       IFNULL(sValue.en,sValue.se) sValue
  FROM itemdata d
  JOIN strings sTag ON idTag = sTag.idString
  JOIN strings sValue ON idValue = sValue.idString
 WHERE d.idItem = 1
ORDER BY sTag

如果没有定义任何内容(空),则 IFNULL 允许我选择首选语言和默认语言。我最终得到这个结果。

idItem  idTag  idValue  sTag    sValue
------------------------------------------
1       9      6        Brand   Nokia
1       3      5        Color   Red
1       3      4        Color   Svart
1       11     8        Type    Cell phone

问题

正如您在上面的结果中看到的,有两个名为 Color 的标签(具有不同的值)。 我想做的是将标签 Color 的 sValues CONCAT 到一个标签中,如下所示:

idItem  idTag  idValue  sTag    sValue
------------------------------------------
1       9      6        Brand   Nokia
1       3      5        Color   Red,Svart
1       11     8        Type    Cell phone

我一直在查看 GROUP_CONCAT 但它似乎只是组合了一整列。

MySQL测试数据库创建

-- MySQL Administrator dump 1.4
--
-- ------------------------------------------------------
-- Server version   5.1.47-community

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;

--
-- Create schema test
--

CREATE DATABASE IF NOT EXISTS test;
USE test;

--
-- Definition of table `itemdata`
--

DROP TABLE IF EXISTS `itemdata`;
CREATE TABLE `itemdata` (
  `idItem` int(10) unsigned NOT NULL,
  `idTag` int(10) unsigned NOT NULL,
  `idValue` int(10) unsigned NOT NULL,
  KEY `iPrimary` (`idItem`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='All item tags';

--
-- Dumping data for table `itemdata`
--

/*!40000 ALTER TABLE `itemdata` DISABLE KEYS */;
INSERT INTO `itemdata` (`idItem`,`idTag`,`idValue`) VALUES 
 (1,3,5),
 (1,9,6),
 (1,11,8),
 (2,3,4),
 (2,9,7),
 (2,11,8),
 (1,3,4);
/*!40000 ALTER TABLE `itemdata` ENABLE KEYS */;

--
-- Definition of table `strings`
--

DROP TABLE IF EXISTS `strings`;
CREATE TABLE `strings` (
  `idString` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `SE` varchar(45) DEFAULT NULL,
  `EN` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`idString`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COMMENT='International strings';

--
-- Dumping data for table `strings`
--

/*!40000 ALTER TABLE `strings` DISABLE KEYS */;
INSERT INTO `strings` (`idString`,`SE`,`EN`) VALUES 
 (1,'Svenska',NULL),
 (2,NULL,'English'),
 (3,'Färg','Color'),
 (4,'Svart',NULL),
 (5,'Röd','Red'),
 (6,'Nokia',NULL),
 (7,'Samsung',NULL),
 (8,'Mobiltelefon','Cell phone'),
 (9,'Produkt märke','Brand'),
 (10,'Språk','Language'),
 (11,'Typ','Type');
/*!40000 ALTER TABLE `strings` ENABLE KEYS */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

I have one table with localized strings and one table creating tags with values by combining and referring to the idString in table Strings. At the bottom you can find a MySQL script to create all this data.

Strings

idString  SE             EN
--------------------------------
3         Färg           Color
4         Svart          <null>
5         Röd            Red
6         Nokia          <null>
8         Mobiltelefon   Cell phone
9         Produkt märke  Brand
11        Typ            Type

TABLE: ItemData
idItem  idTag  idValue
--------------------------------
1       9      6      
1       3      5      
1       3      4      
1       11     8       

I issue this SQL statemenet (feel free to suggest any optimization) to lookup the idTag and idValue in table Strings and retrieve their text values.

SELECT d.*,
       IFNULL(sTag.en,sTag.se) sTag,
       IFNULL(sValue.en,sValue.se) sValue
  FROM itemdata d
  JOIN strings sTag ON idTag = sTag.idString
  JOIN strings sValue ON idValue = sValue.idString
 WHERE d.idItem = 1
ORDER BY sTag

The IFNULL lets me select a preferred language and a default language if there is nothing defined (null). I end up with this result.

idItem  idTag  idValue  sTag    sValue
------------------------------------------
1       9      6        Brand   Nokia
1       3      5        Color   Red
1       3      4        Color   Svart
1       11     8        Type    Cell phone

Problem

As you can see in the above result there are two tags named Color (with different values).
What I would like to do is to CONCAT the sValues for the tag Color into one tag like this:

idItem  idTag  idValue  sTag    sValue
------------------------------------------
1       9      6        Brand   Nokia
1       3      5        Color   Red,Svart
1       11     8        Type    Cell phone

I have been looking at GROUP_CONCAT but it seems only to combine a whole column.

MySQL test database creation

-- MySQL Administrator dump 1.4
--
-- ------------------------------------------------------
-- Server version   5.1.47-community

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;

--
-- Create schema test
--

CREATE DATABASE IF NOT EXISTS test;
USE test;

--
-- Definition of table `itemdata`
--

DROP TABLE IF EXISTS `itemdata`;
CREATE TABLE `itemdata` (
  `idItem` int(10) unsigned NOT NULL,
  `idTag` int(10) unsigned NOT NULL,
  `idValue` int(10) unsigned NOT NULL,
  KEY `iPrimary` (`idItem`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='All item tags';

--
-- Dumping data for table `itemdata`
--

/*!40000 ALTER TABLE `itemdata` DISABLE KEYS */;
INSERT INTO `itemdata` (`idItem`,`idTag`,`idValue`) VALUES 
 (1,3,5),
 (1,9,6),
 (1,11,8),
 (2,3,4),
 (2,9,7),
 (2,11,8),
 (1,3,4);
/*!40000 ALTER TABLE `itemdata` ENABLE KEYS */;

--
-- Definition of table `strings`
--

DROP TABLE IF EXISTS `strings`;
CREATE TABLE `strings` (
  `idString` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `SE` varchar(45) DEFAULT NULL,
  `EN` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`idString`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COMMENT='International strings';

--
-- Dumping data for table `strings`
--

/*!40000 ALTER TABLE `strings` DISABLE KEYS */;
INSERT INTO `strings` (`idString`,`SE`,`EN`) VALUES 
 (1,'Svenska',NULL),
 (2,NULL,'English'),
 (3,'Färg','Color'),
 (4,'Svart',NULL),
 (5,'Röd','Red'),
 (6,'Nokia',NULL),
 (7,'Samsung',NULL),
 (8,'Mobiltelefon','Cell phone'),
 (9,'Produkt märke','Brand'),
 (10,'Språk','Language'),
 (11,'Typ','Type');
/*!40000 ALTER TABLE `strings` ENABLE KEYS */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心病无药医 2024-11-17 09:51:34

我还没有测试过这个:

SELECT d.idItem, 
       d.idTag,
       IFNULL(sTag.en,sTag.se) sTag,
       GROUP_CONCAT(IFNULL(sValue.en,sValue.se)) sValue
  FROM itemdata d
  JOIN strings sTag ON idTag = sTag.idString
  JOIN strings sValue ON idValue = sValue.idString
 WHERE d.idItem = 1
 GROUP BY d.idItem, d.idTag, IFNULL(sTag.en,sTag.se)
 ORDER BY sTag

I haven't tested this:

SELECT d.idItem, 
       d.idTag,
       IFNULL(sTag.en,sTag.se) sTag,
       GROUP_CONCAT(IFNULL(sValue.en,sValue.se)) sValue
  FROM itemdata d
  JOIN strings sTag ON idTag = sTag.idString
  JOIN strings sValue ON idValue = sValue.idString
 WHERE d.idItem = 1
 GROUP BY d.idItem, d.idTag, IFNULL(sTag.en,sTag.se)
 ORDER BY sTag
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文