我想写一个带有一些固定列和动态列的选择语句。这里的动态列名称是另一个表中的行。
我试过这个,但得到错误。请告诉我我的错误在哪里
set @sql=(Select subject from tbl_subjects where C_Id=22);
SELECT
ta.rollno,
ta.StdNm,
tc.C_Name,
@sql
FROM
tbl_cmarks tm,
tbl_admission ta,
tbl_classes tc
WHERE
tm.Cid = tc.C_Id
AND ta.rollno = tm.rollno
AND tm.Cid = 22 and tm.Examid=9
Run Code Online (Sandbox Code Playgroud)
Mysql 显示:
错误代码:1242。子查询返回多于 1 行
谁能告诉我如何在mysql中做到这一点?
Tar*_*ryn 12
查看您的表结构,我建议您将设计更改为标准化的设计。例如:
create table tbl_subjects
(
sub_id int,
subject_name varchar(25)
);
create table tbl_cmarks
(
c_id int,
examid int,
rollno int,
sub_id int,
mark int
);
Run Code Online (Sandbox Code Playgroud)
使用类似于上面的内容将允许您添加新主题而无需更改您的表格。然后,您只需加入 上的表格sub_id
即可获得每个班级的科目列表。
select ta.rollno,ta.StdNm,tc.C_Name,
tm.mark,
s.subject
FROM tbl_cmarks tm
INNER JOIN tbl_classes tc
ON tm.Cid = tc.C_Id
INNER JOIN tbl_admission ta
ON ta.rollno = tm.rollno
INNER JOIN tbl_subjects s
on tm.sub_id = s.sub_id
where tm.Cid = 22
and tm.Examid=9;
Run Code Online (Sandbox Code Playgroud)
请参阅SQL Fiddle with Demo。以上将为您提供行中的结果,但您可以轻松地应用带有 CASE 表达式的聚合函数将数据转换为列。类似于以下内容:
select ta.rollno,
ta.StdNm,
tc.C_Name,
max(case when s.subject = 'English' then tm.mark end) Emglish,
max(case when s.subject = 'Physics' then tm.mark end) Physics
FROM tbl_cmarks tm
INNER JOIN tbl_classes tc
ON tm.Cid = tc.C_Id
INNER JOIN tbl_admission ta
ON ta.rollno = tm.rollno
INNER JOIN tbl_subjects s
on tm.sub_id = s.sub_id
where tm.Cid = 22
and tm.Examid=9
group by ta.rollno, ta.StdNm, tc.C_Name;
Run Code Online (Sandbox Code Playgroud)
见演示。
但是如果你不改变你当前的表结构,如果你不知道你将要返回的列,那么你将不得不实现一个准备好的语句来生成动态 SQL。
首先,您将创建类列表:
set @sqlList = null;
set @query = null;
SELECT
GROUP_CONCAT(concat('tm.', subject))
INTO @sqlList
FROM tbl_subjects
where C_Id=22;
Run Code Online (Sandbox Code Playgroud)
见演示。这将为您提供每个c_id
. 获得类列表后,您可以将其添加到 sql 字符串的其余部分,以便完整代码为:
set @sqlList = null;
set @query = null;
SELECT
GROUP_CONCAT(concat('tm.', subject))
INTO @sqlList
FROM tbl_subjects
where C_Id=22;
SET @query
= CONCAT('SELECT ta.rollno,ta.StdNm,tc.C_Name, ', @sqlList, '
FROM tbl_cmarks tm
INNER JOIN tbl_classes tc
ON tm.Cid = tc.C_Id
INNER JOIN tbl_admission ta
ON ta.rollno = tm.rollno
where tm.Cid = 22
and tm.Examid=9');
PREPARE stmt FROM @query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Run Code Online (Sandbox Code Playgroud)