MySQL 查询通过加入 4 个不同的表来创建数据透视表

2021-12-19 00:00:00 matrix pivot-table mysql

我有 4 个 mySQL 表,分别是 Exams、Marks、Student 和 Subject.下面提供了带有数据的 Sql.我需要如下截图所示的输出.

分数是根据特定科目和学生对的所有分数加在一起计算得出的,并具有适当的权重百分比(忽略权重为 0 的考试)

我尝试使用以下查询,但结果没有给出累积分数,因此需要帮助.

SET @sql = NULL;选择GROUP_CONCAT(DISTINCT)CONCAT('MAX(IF(sj.SubjectId = ''', SubjectId,''', pa.Marks, NULL)) AS ',SubjectId)) 进入@sql从主题;SET @sql = CONCAT('SELECT s.ID, s.StudentID, s.FirstName, s.LastName, ', @sql, '来自学生JOIN 标记为 paON pa.StudentID = s.StudentID AND pa.OrganizationId = s.OrganizationId参加考试在 p.ExamId = pa.ExamId AND p.OrganizationId = pa.OrganizationId加入主题 sjON p.SubjectId = sj.SubjectId AND pa.OrganizationId = sj.OrganizationIdWHERE p.Weightage >0GROUP BY s.ID');从@sql 准备 stmt;执行 stmt;

请帮忙.小提琴链接

<代码>创建表`考试`(`ID` int(6) 非空,`ExamId` varchar(20) COLLATE utf8_unicode_ci NOT NULL,`Name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,`Date` 日期时间(6) DEFAULT NULL,`TotalMarks` int(6) 非空,`SubjectId` varchar(30) COLLATE utf8_unicode_ci NOT NULL,`Weightage` int(6) NOT NULL DEFAULT '0',`OrganizationId` int(6) 非空) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;——-- 转储表`Exams`的数据——插入`考试`(`ID`、`ExamId`、`Name`、`Date`、`TotalMarks`、`SubjectId`、`Weightage`、`OrganizationId`)值(8, 'EX_0001', '测试 1', '2020-05-30 17:15:38.000000', 50, 'SUB_0002', 0, 116),(9, 'EX_0002', '测试 2', '2020-05-17 17:15:19.000000', 30, 'SUB_0001', 0, 116),(10, 'EX_0003', '测试 3', '2020-05-17 17:15:51.000000', 30, 'SUB_0003', 10, 116),(11, 'EX_0004', 'Test 45', '2020-05-19 15:15:08.000000', 30, 'SUB_0001', 0, 116),(12, 'EX_0005', '期末考试', '2020-05-20 15:30:53.000000', 100, 'SUB_0001', 80, 116),(13, 'EX_0006', 'Terminal 3', '2020-05-20 15:30:03.000000', 50, 'SUB_0001', 10, 116);----------------------------------------------------------——-- 表`Marks`的表结构——创建表`标记`(`ID` int(11) 非空,`StudentId` varchar(30) COLLATE utf8_unicode_ci NOT NULL,`ExamId` varchar(30) COLLATE utf8_unicode_ci NOT NULL,`Marks` int(6) 不为空,`OrganizationId` int(6) 非空) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;——-- 转储表`Marks`的数据——INSERT INTO `Marks`(`ID`、`StudentId`、`ExamId`、`Marks`、`OrganizationId`)值(14, 'S_100000001', 'EX_0004', 30, 116),(15, 'S_100000001', 'EX_0003', 25, 116),(16, 'S_100000001', 'EX_0002', 77, 116),(17, 'S_100000003', 'EX_0003', 15, 116),(18, 'S_100000003', 'EX_0004', 12, 116),(19, 'S_100000003', 'EX_0001', 12, 116),(20, 'S_100000002', 'EX_0004', 20, 116),(21, 'S_100000002', 'EX_0003', 21, 116),(22, 'S_100000001', 'EX_0005', 80, 116),(23, 'S_100000002', 'EX_0005', 90, 116);----------------------------------------------------------——-- 表`Student`的表结构——创建表`学生`(`ID` int(6) 非空,`GradeId` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,`StudentID` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,`OrganizationId` int(6) DEFAULT NULL,`FirstName` varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,`LastName` varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,`FatherFirstName` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,`FatherLastName` varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,`DateOfBirth` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,`PlaceOfBirth` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,`Sex` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,`Carnet` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,`MobilePhone` bigint(8) DEFAULT NULL,`地址` varchar(60) COLLATE utf8_unicode_ci DEFAULT NULL,`MotherFirstName` varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,`MotherLastName` varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,`FatherMobilePhone` bigint(8) DEFAULT NULL,`MotherMobilePhone` bigint(8) DEFAULT NULL,`FatherProfession` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,`MotherProfession` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,`观察` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;——-- 转储表 `Student` 的数据——插入 `Student`(`ID`、`GradeId`、`StudentID`、`OrganizationId`、`FirstName`、`LastName`、`FatherFirstName`、`FatherLastName`、`DateOfBirth`、`PlaceOfBirth`、`Sex`、`Carnet`、`MobilePhone`、`Address`、`MotherFirstName`、`MotherLastName`、`FatherMobilePhone`、`MotherMobilePhone`、`FatherProfession`、`MotherProfession`、`Observations`)值(21, 'G_016', 'S_100000001', 116, '学生', '一', '', '', '', '', '男', NULL, 8178109047, '', '', '',0, 0, NULL, NULL, NULL),(22, 'G_016', 'S_100000002', 116, '学生', '二', '', '', '', '', 'female', NULL, 0, '', '', '',0, 0, NULL, NULL, NULL),(23, 'G_002', 'S_100000003', 116, 'Student3', '三', NULL, NULL, NULL, NULL, '男', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 空值);----------------------------------------------------------——-- 表`Subject`的表结构——创建表`主题`(`ID` int(6) 非空,`SubjectId` varchar(20) COLLATE utf8_unicode_ci NOT NULL,`Name` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,`缩写` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,`GradeId` varchar(10) COLLATE utf8_unicode_ci NOT NULL,`OrganizationId` int(6) 非空,`StaffId` varchar(30) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0') ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;——-- 转储主题"表的数据——INSERT INTO `Subject`(`ID`、`SubjectId`、`Name`、`Abbreviation`、`GradeId`、`OrganizationId`、`StaffId`)值(12, 'SUB_0001', 'English 1A', 'Eng_1A', 'G_016', 116, 'E_100000030'),(13, 'SUB_0002', 'English 1B', 'Eng_1B', 'G_002', 116, '0'),(14, 'SUB_0003', '科学 1A', 'Sci_1A', 'G_016', 116, 'E_100000030');

解决方案

好的,你的最后一条评论,你的查询看起来像这样

<块引用>

SET @sql = NULL;选择GROUP_CONCAT(DISTINCT)CONCAT('SUM(IF(sj.SubjectId = ''', SubjectId,''', ROUND((pa.`Marks` * p.`Weightage`/100),1),0)) AS ',SubjectId)) 进入@sql从主题;SET @sql = CONCAT('SELECT s.ID, s.StudentID, s.FirstName, s.LastName, ', @sql, '来自学生JOIN 标记为 paON pa.StudentID = s.StudentID AND pa.OrganizationId = s.OrganizationId参加考试在 p.ExamId = pa.ExamId AND p.OrganizationId = pa.OrganizationId加入主题 sjON p.SubjectId = sj.SubjectId AND pa.OrganizationId = sj.OrganizationIdWHERE p.Weightage >0按 s.ID 分组按 s.ID 排序');#选择@sql;从@sql 准备 stmt;执行 stmt;

<前>身份证 |学生证 |名字 |姓氏 |SUB_0001 |SUB_0002 |SUB_0003-: |:---------- |:-------- |:------- |-------: |-------: |-------:21 |S_100000001 |学生 |一 |71.7 |0.0 |2.522 |S_100000002 |学生 |二 |72.0 |0.0 |2.123 |S_100000003 |学生3 |三 |0.0 |1.2 |1.5

db<>fiddle 这里

I have 4 mySQL tables namely Exams, Marks, Student and Subject. Sql with data is provided below. I need the output like below screenshot.

Marks is calculated from all Marks added together for the particular subject and student pair with their proper Weightage in Percentage (Exams with 0 Weightage are ignored)

I tried using the below query but the result didn't gave the cumulative marks so need help.

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
               CONCAT('MAX(IF(sj.SubjectId = ''', SubjectId,''', pa.Marks, NULL)) AS ',SubjectId)
              ) INTO @sql
FROM Subject;

SET @sql = CONCAT('SELECT s.ID, s.StudentID, s.FirstName, s.LastName, ', @sql, ' 
                  FROM Student s
                  JOIN Marks AS pa 
                  ON pa.StudentID = s.StudentID AND pa.OrganizationId = s.OrganizationId 
                  JOIN Exams p
                  ON p.ExamId = pa.ExamId AND p.OrganizationId = pa.OrganizationId
                  JOIN Subject sj
                  ON p.SubjectId = sj.SubjectId AND pa.OrganizationId = sj.OrganizationId
                  WHERE p.Weightage > 0
                  GROUP BY s.ID');

PREPARE stmt FROM @sql;
EXECUTE stmt;

Please help. FIDDLE LINK


CREATE TABLE `Exams` (
  `ID` int(6) NOT NULL,
  `ExamId` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
  `Name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `Date` datetime(6) DEFAULT NULL,
  `TotalMarks` int(6) NOT NULL,
  `SubjectId` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `Weightage` int(6) NOT NULL DEFAULT '0',
  `OrganizationId` int(6) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--
-- Dumping data for table `Exams`
--

INSERT INTO `Exams` (`ID`, `ExamId`, `Name`, `Date`, `TotalMarks`, `SubjectId`, `Weightage`, `OrganizationId`) VALUES
(8, 'EX_0001', 'Test 1', '2020-05-30 17:15:38.000000', 50, 'SUB_0002', 0, 116),
(9, 'EX_0002', 'Test 2', '2020-05-17 17:15:19.000000', 30, 'SUB_0001', 0, 116),
(10, 'EX_0003', 'Test 3', '2020-05-17 17:15:51.000000', 30, 'SUB_0003', 10, 116),
(11, 'EX_0004', 'Test 45', '2020-05-19 15:15:08.000000', 30, 'SUB_0001', 0, 116),
(12, 'EX_0005', 'Final Exam', '2020-05-20 15:30:53.000000', 100, 'SUB_0001', 80, 116),
(13, 'EX_0006', 'Terminal 3', '2020-05-20 15:30:03.000000', 50, 'SUB_0001', 10, 116);

-- --------------------------------------------------------

--
-- Table structure for table `Marks`
--

CREATE TABLE `Marks` (
  `ID` int(11) NOT NULL,
  `StudentId` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `ExamId` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `Marks` int(6) NOT NULL,
  `OrganizationId` int(6) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--
-- Dumping data for table `Marks`
--

INSERT INTO `Marks` (`ID`, `StudentId`, `ExamId`, `Marks`, `OrganizationId`) VALUES
(14, 'S_100000001', 'EX_0004', 30, 116),
(15, 'S_100000001', 'EX_0003', 25, 116),
(16, 'S_100000001', 'EX_0002', 77, 116),
(17, 'S_100000003', 'EX_0003', 15, 116),
(18, 'S_100000003', 'EX_0004', 12, 116),
(19, 'S_100000003', 'EX_0001', 12, 116),
(20, 'S_100000002', 'EX_0004', 20, 116),
(21, 'S_100000002', 'EX_0003', 21, 116),
(22, 'S_100000001', 'EX_0005', 80, 116),
(23, 'S_100000002', 'EX_0005', 90, 116);

-- --------------------------------------------------------

--
-- Table structure for table `Student`
--

CREATE TABLE `Student` (
  `ID` int(6) NOT NULL,
  `GradeId` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
  `StudentID` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,
  `OrganizationId` int(6) DEFAULT NULL,
  `FirstName` varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `LastName` varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `FatherFirstName` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,
  `FatherLastName` varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `DateOfBirth` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,
  `PlaceOfBirth` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,
  `Sex` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,
  `Carnet` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,
  `MobilePhone` bigint(8) DEFAULT NULL,
  `Address` varchar(60) COLLATE utf8_unicode_ci DEFAULT NULL,
  `MotherFirstName` varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `MotherLastName` varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `FatherMobilePhone` bigint(8) DEFAULT NULL,
  `MotherMobilePhone` bigint(8) DEFAULT NULL,
  `FatherProfession` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,
  `MotherProfession` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,
  `Observations` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--
-- Dumping data for table `Student`
--

INSERT INTO `Student` (`ID`, `GradeId`, `StudentID`, `OrganizationId`, `FirstName`, `LastName`, `FatherFirstName`, `FatherLastName`, `DateOfBirth`, `PlaceOfBirth`, `Sex`, `Carnet`, `MobilePhone`, `Address`, `MotherFirstName`, `MotherLastName`, `FatherMobilePhone`, `MotherMobilePhone`, `FatherProfession`, `MotherProfession`, `Observations`) VALUES
(21, 'G_016', 'S_100000001', 116, 'Student', 'One', '', '', '', '', 'male', NULL, 8178109047, '', '', '', 0, 0, NULL, NULL, NULL),
(22, 'G_016', 'S_100000002', 116, 'Student', 'two', '', '', '', '', 'female', NULL, 0, '', '', '', 0, 0, NULL, NULL, NULL),
(23, 'G_002', 'S_100000003', 116, 'Student3', 'three', NULL, NULL, NULL, NULL, 'male', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);

-- --------------------------------------------------------

--
-- Table structure for table `Subject`
--

CREATE TABLE `Subject` (
  `ID` int(6) NOT NULL,
  `SubjectId` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
  `Name` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,
  `Abbreviation` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,
  `GradeId` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
  `OrganizationId` int(6) NOT NULL,
  `StaffId` varchar(30) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--
-- Dumping data for table `Subject`
--

INSERT INTO `Subject` (`ID`, `SubjectId`, `Name`, `Abbreviation`, `GradeId`, `OrganizationId`, `StaffId`) VALUES
(12, 'SUB_0001', 'English 1A', 'Eng_1A', 'G_016', 116, 'E_100000030'),
(13, 'SUB_0002', 'English 1B', 'Eng_1B', 'G_002', 116, '0'),
(14, 'SUB_0003', 'Science 1A', 'Sci_1A', 'G_016', 116, 'E_100000030');


解决方案

Ok with your last comment, your query would look like this

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
               CONCAT('SUM(IF(sj.SubjectId = ''', SubjectId,''', ROUND((pa.`Marks` * p.`Weightage` / 100),1),0)) AS ',SubjectId)
              ) INTO @sql
FROM Subject;

SET @sql = CONCAT('SELECT s.ID, s.StudentID, s.FirstName, s.LastName, ', @sql, ' 
                  FROM Student s
                  JOIN Marks AS pa 
                  ON pa.StudentID = s.StudentID AND pa.OrganizationId = s.OrganizationId 
                  JOIN Exams p
                  ON p.ExamId = pa.ExamId AND p.OrganizationId = pa.OrganizationId
                  JOIN Subject sj
                  ON p.SubjectId = sj.SubjectId AND pa.OrganizationId = sj.OrganizationId
                  WHERE p.Weightage > 0
                 GROUP BY s.ID
                 ORDER BY s.ID');
#SELECT @sql;
PREPARE stmt FROM @sql;
EXECUTE stmt;



ID | StudentID   | FirstName | LastName | SUB_0001 | SUB_0002 | SUB_0003
-: | :---------- | :-------- | :------- | -------: | -------: | -------:
21 | S_100000001 | Student   | One      |     71.7 |      0.0 |      2.5
22 | S_100000002 | Student   | two      |     72.0 |      0.0 |      2.1
23 | S_100000003 | Student3  | three    |      0.0 |      1.2 |      1.5

db<>fiddle here

相关文章