我在MySQL中有这个数据结构:
+-----------+-----------+--------------+
| name | barcode | factory_code |
+-----------+-----------+--------------+
| product 1 | 123456789 | |
| product 2 | 987654321 | |
| product 3 | | AAAAAAAAAAAA |
| product 4 | | BBBBBBBBBBBB |
| product 5 | 111111111 | CCCCCCCCCCCC |
+-----------+-----------+--------------+
现在我需要生成此结果并以HTML格式显示:
+-----------+-------------------------+
| name | code |
+-----------+-------------------------+
| product 1 | 123456789 |
| product 2 | 987654321 |
| product 3 | AAAAAAAAAAAA |
| product 4 | BBBBBBBBBBBB |
| product 5 | 111111111, CCCCCCCCCCCC |
+-----------+-------------------------+
字段不是NULL
,只是空。
我认为我直接使用MySQL查询生成此代码,以减少编码,并且可能会更快地工作。我可以使用PHP的/ Perl的join
函数来完成它。
可以在MySQL中直接进行吗?
答案 0 :(得分:5)
您可以使用concat_ws()
in MySQL。由于您没有NULL
空字符串,因此您需要实现一些逻辑来过滤掉这些空字段。
SELECT
name,
concat_ws(
', ',
IF(barcode > "", barcode, NULL),
IF(factory_code > "", factory_code, NULL)
) as 'code'
FROM Table1;
如Borodin points out in his comment,如果barcode
包含空格或控制字符,那么它将不等于空字符串,因此barcode = ""
将失败,结果将是一个虚假的逗号。但MySQL空间扩展了比较的两个参数,因此任何包含非空格字符的内容都将“大于”任何不包含非空格字符的内容。 IF (barcode > "", barcode, NULL)
转向NULL
任何只是控制字符(HT,LF,CR等)或空格的内容。
试试here。
然而,让数据库做到这一点并不会给你更多的速度。对于这个相当少量的数据,它可以忽略不计,我认为它甚至不值得考虑。
在Perl中,您还必须添加对空字符串的检查。
while (my $res = $sth->fetchrow_arrayref) {
my $name = shift @$res;
my $code = join ', ', grep { $_ } @$res;
# and then do stuff
}
grep { $_ } @$res
过滤掉所有不被视为 true value 的值。也就是说,空字符串以及NULL
值,由undef
表示。
从维护的角度来看(如果这很重要),在应用程序而不是SQL中执行它是优选的 1 。如果它是一次性代码,我个人会选择那个让我思路最少的代码。
1)也就是说,如果我们讨论的是在一个小应用程序中混合的纯SQL。在更大的范围内,如果有实际的模型层,我会将聚合移动到该模型中。
答案 1 :(得分:0)
你可以尝试这样的事情:
SET @a := 'abc';
SET @b :='def';
SELECT CONCAT(@a, IF(LENGTH(@a) >0 AND LENGTH(@b) >0,',',''), @b)
将@a
替换为barcode
,将@b
替换为factory_code
在您的情况下:
SELECT
name,
CONCAT(
barcode,
IF(LENGTH(barcode) > 0 AND LENGTH(factory_code) > 0, ',', ''),
factory_code
) AS 'code'
FROM t;
WORKING DEMO 当@a和@b非空时
WORKING DEMO 当@a为空且@b非空
WORKING DEMO 当@a非空且@b为空
WORKING DEMO 当@a和@b为空时
答案 2 :(得分:0)
我找到了一个基于1000111答案的简单解决方案。
SELECT CONCAT_WS(', ',
IF( LENGTH(barcode) > 0, barcode, NULL),
IF( LENGTH(factory_code) > 0, factory_code, NULL) AS code
FROM tablename;
答案 3 :(得分:-1)
SELECT name, TRIM(',' FROM TRIM(CONCAT_WS(', ', barcode, factory_code))) as code ...