查询以返回单行,其中多个项目位于行内的不同列中

Posted

技术标签:

【中文标题】查询以返回单行,其中多个项目位于行内的不同列中【英文标题】:query to return a single row with the multiple items in separate columns within the row 【发布时间】:2011-02-03 20:15:40 【问题描述】:

我有一种情况,我返回多行的结果。我正在寻找一种返回单行的方法,该行中的多个项目位于不同的列中。我的初始查询:

SELECT a.name, a.city, a.address, a.abbrv, b.urltype, b.url 
FROM jos__universityTBL as a 
LEFT JOIN jos__university_urlTBL as b on b.universityID = a.ID 
WHERE a.stateVAL = 'CA'

我的输出:

| University Of Southern Califor         | Los Angeles         |         | usc   |       2 | http://web-app.usc.edu/ws/soc/api/                                                                                                       | 
| University Of Southern Califor         | Los Angeles         |         | usc   |       4 | http://web-app.usc.edu/ws/soc/api/                                                                                                      | 
| University Of Southern Califor         | Los Angeles         |         | usc   |       1 | www.usc.edu                                                                                                                             | 
| San Jose State University              | San Jose            |         | sjsu  |       2 | http://info.sjsu.edu/home/schedules.html                                                                                                | 
| San Jose State University              | San Jose            |         | sjsu  |       4 | https://cmshr.sjsu.edu/psp/HSJPRDF/EMPLOYEE/HSJPRD/c/COMMUNITY_ACCESS.CLASS_SEARCH.GBL?FolderPath=PORTAL_ROOT_OBJECT.PA_HC_CLASS_SEARCH | 
| San Jose State University              | San Jose            |         | sjsu  |       1 | www.sjsu.edu                                                                                                                            

我的表架构...

mysql> describe jos_universityTBL;
+----------------+--------------+------+-----+---------+----------------+
| Field          | Type         | Null | Key | Default | Extra          |
+----------------+--------------+------+-----+---------+----------------+
| name           | varchar(50)  | NO   | UNI |         |                | 
| repos_dir_name | varchar(50)  | NO   |     |         |                | 
| city           | varchar(20)  | YES  |     |         |                | 
| stateVAL       | varchar(5)   | NO   |     |         |                | 
| address        | varchar(50)  | NO   |     |         |                | 
| abbrv          | varchar(20)  | NO   |     |         |                | 
| childtbl       | varchar(200) | NO   |     |         |                | 
| userID         | int(10)      | NO   |     | 0       |                | 
| ID             | int(10)      | NO   | PRI | NULL    | auto_increment | 
+----------------+--------------+------+-----+---------+----------------+
9 rows in set (0.00 sec)

mysql> describe jos_university_urlTBL;
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| universityID | int(10)      | NO   |     | 0       |                | 
| urltype      | int(5)       | NO   |     | 0       |                | 
| url          | varchar(200) | NO   | MUL |         |                | 
| actionID     | int(5)       | YES  |     | 0       |                | 
| status       | int(5)       | YES  |     | 0       |                | 
| ID           | int(10)      | NO   | PRI | NULL    | auto_increment | 
+--------------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)

我真的很想得到类似的东西:

                                 |<<the concated urltype-url >>|
ucs  |  losangeles   |  usc.edu  |  1-u1 |  2-u2 |  3-u2   |

【问题讨论】:

【参考方案1】:

你可以使用group_concat:

SELECT a.name, a.city, a.address, a.abbrv, b.urltype, 
    group_concat(b.url SEPARATOR ' ')
FROM jos__universityTBL as a 
LEFT JOIN jos__university_urlTBL as b on b.universityID = a.ID 
WHERE a.stateVAL = 'CA'
GROUP BY a.name, a.city, a.address, a.abbrv, b.urltype

在 SQL 中很难生成动态列;如果可能的话,看看它是否可以移动到客户端。如果没有,您可以在子查询中添加行号,并为每个行号提供自己的列。这是一个略有不同的表的示例:

drop table if exists Universities;
drop table if exists Urls;
create table Universities (
  id int auto_increment primary key
, Name varchar(50)
);
create table Urls (
  id int auto_increment primary key
, UniversityId int
, Url varchar(50)
);
insert into Universities (name) values ('USC'), ('SJSU');
insert into Urls (UniversityId, Url) values 
    (1,'http://a/'), (1,'http://b/'),
    (2,'http://c/'), (2,'http://d/'), (2,'http://e/');

SELECT
    Name
,   group_concat(case RowNr when 1 then Url end) as FirstCol
,   group_concat(case RowNr when 2 then Url end) as SecondCol
,   group_concat(case RowNr when 3 then Url end) as ThirdCol
FROM (
    SELECT 
        u.Name
    ,   l.Url
    ,   (@i := case when @LastUni = u.Name then @i + 1 else 1 end) as RowNr
    ,   @LastUni := u.name
    FROM Universities u
    JOIN Urls l ON u.id = l.UniversityId
    JOIN (SELECT @i := 0, @LastUni := '') init
) subquery
GROUP BY Name;

打印出来:

SJSU     http://c/  http://d/   http://e/
USC      http://a/  http://b/   NULL

【讨论】:

是的,我要说的是,可能希望分隔符作为一些特殊字符,如 SEPERATOR '|'

以上是关于查询以返回单行,其中多个项目位于行内的不同列中的主要内容,如果未能解决你的问题,请参考以下文章

查询以从与给定值相同的列中选择值,但不同的行

如何合并为单行表返回多个数据的子查询?

从同一个表中的多个列中选择不同的值

oracle查询将不同的列填充到一列中

SQL查询从键表中选择多个条目到同一行的不同列中

我希望查询应该返回员工的所有结果,无论员工的姓名是不是在不同的列中