模擬數據:
大多數數據庫存儲的數據都是這樣,但是實際業務則需要我們對數據進行處理如下:
這就是很多時候面試也會遇到的列傳行的問題。
創建數據庫以及數據:

USE [master] GO /****** Object: Database [MyStudy] Script Date: 2018/6/5 23:27:15 ******/ CREATE DATABASE [MyStudy] CONTAINMENT = NONE ON PRIMARY ( NAME = N'MyStudy', FILENAME = N'E:\Data\MyStudy.mdf' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ) LOG ON ( NAME = N'MyStudy_log', FILENAME = N'E:\Data\MyStudy_log.ldf' , SIZE = 2048KB , MAXSIZE = 2048GB , FILEGROWTH = 10%) GO ALTER DATABASE [MyStudy] SET COMPATIBILITY_LEVEL = 120 GO IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled')) begin EXEC [MyStudy].[dbo].[sp_fulltext_database] @action = 'enable' end GO ALTER DATABASE [MyStudy] SET ANSI_NULL_DEFAULT OFF GO ALTER DATABASE [MyStudy] SET ANSI_NULLS OFF GO ALTER DATABASE [MyStudy] SET ANSI_PADDING OFF GO ALTER DATABASE [MyStudy] SET ANSI_WARNINGS OFF GO ALTER DATABASE [MyStudy] SET ARITHABORT OFF GO ALTER DATABASE [MyStudy] SET AUTO_CLOSE OFF GO ALTER DATABASE [MyStudy] SET AUTO_SHRINK OFF GO ALTER DATABASE [MyStudy] SET AUTO_UPDATE_STATISTICS ON GO ALTER DATABASE [MyStudy] SET CURSOR_CLOSE_ON_COMMIT OFF GO ALTER DATABASE [MyStudy] SET CURSOR_DEFAULT GLOBAL GO ALTER DATABASE [MyStudy] SET CONCAT_NULL_YIELDS_NULL OFF GO ALTER DATABASE [MyStudy] SET NUMERIC_ROUNDABORT OFF GO ALTER DATABASE [MyStudy] SET QUOTED_IDENTIFIER OFF GO ALTER DATABASE [MyStudy] SET RECURSIVE_TRIGGERS OFF GO ALTER DATABASE [MyStudy] SET DISABLE_BROKER GO ALTER DATABASE [MyStudy] SET AUTO_UPDATE_STATISTICS_ASYNC OFF GO ALTER DATABASE [MyStudy] SET DATE_CORRELATION_OPTIMIZATION OFF GO ALTER DATABASE [MyStudy] SET TRUSTWORTHY OFF GO ALTER DATABASE [MyStudy] SET ALLOW_SNAPSHOT_ISOLATION OFF GO ALTER DATABASE [MyStudy] SET PARAMETERIZATION SIMPLE GO ALTER DATABASE [MyStudy] SET READ_COMMITTED_SNAPSHOT OFF GO ALTER DATABASE [MyStudy] SET HONOR_BROKER_PRIORITY OFF GO ALTER DATABASE [MyStudy] SET RECOVERY FULL GO ALTER DATABASE [MyStudy] SET MULTI_USER GO ALTER DATABASE [MyStudy] SET PAGE_VERIFY CHECKSUM GO ALTER DATABASE [MyStudy] SET DB_CHAINING OFF GO ALTER DATABASE [MyStudy] SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF ) GO ALTER DATABASE [MyStudy] SET TARGET_RECOVERY_TIME = 0 SECONDS GO ALTER DATABASE [MyStudy] SET DELAYED_DURABILITY = DISABLED GO EXEC sys.sp_db_vardecimal_storage_format N'MyStudy', N'ON' GO USE [MyStudy] GO /****** Object: Table [dbo].[Course] Script Date: 2018/6/5 23:27:16 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[Course]( [ID] [int] IDENTITY(1,1) NOT NULL, [CourseName] [nvarchar](50) NULL, CONSTRAINT [PK_Course] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO /****** Object: Table [dbo].[ScoreAndCourse] Script Date: 2018/6/5 23:27:16 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[ScoreAndCourse]( [CourseID] [int] NOT NULL, [StudentID] [int] NOT NULL, [ID] [int] IDENTITY(1,1) NOT NULL, [Number] [int] NOT NULL, CONSTRAINT [PK_Score] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO /****** Object: Table [dbo].[Students] Script Date: 2018/6/5 23:27:16 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[Students]( [Name] [nvarchar](50) NULL, [ID] [int] IDENTITY(1,1) NOT NULL, [Sex] [int] NOT NULL, CONSTRAINT [PK_Students] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET IDENTITY_INSERT [dbo].[Course] ON INSERT [dbo].[Course] ([ID], [CourseName]) VALUES (1, N'語文') INSERT [dbo].[Course] ([ID], [CourseName]) VALUES (2, N'數學') INSERT [dbo].[Course] ([ID], [CourseName]) VALUES (3, N'英語') INSERT [dbo].[Course] ([ID], [CourseName]) VALUES (4, N'物理') INSERT [dbo].[Course] ([ID], [CourseName]) VALUES (5, N'化學') SET IDENTITY_INSERT [dbo].[Course] OFF SET IDENTITY_INSERT [dbo].[ScoreAndCourse] ON INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (1, 1, 1, 65) INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (1, 2, 2, 70) INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (1, 3, 3, 80) INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (1, 4, 4, 100) INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (2, 1, 5, 80) INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (2, 2, 6, 96) INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (2, 3, 7, 55) INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (2, 4, 8, 76) INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (3, 1, 9, 75) INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (3, 2, 10, 84) INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (3, 3, 11, 69) INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (3, 4, 12, 43) INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (4, 1, 13, 72) INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (4, 2, 14, 89) INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (4, 3, 15, 65) INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (4, 4, 16, 76) INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (5, 1, 17, 88) INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (5, 2, 18, 94) INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (5, 3, 19, 82) INSERT [dbo].[ScoreAndCourse] ([CourseID], [StudentID], [ID], [Number]) VALUES (5, 4, 20, 78) SET IDENTITY_INSERT [dbo].[ScoreAndCourse] OFF SET IDENTITY_INSERT [dbo].[Students] ON INSERT [dbo].[Students] ([Name], [ID], [Sex]) VALUES (N'張三', 1, 0) INSERT [dbo].[Students] ([Name], [ID], [Sex]) VALUES (N'李四', 2, 0) INSERT [dbo].[Students] ([Name], [ID], [Sex]) VALUES (N'王五', 3, 0) INSERT [dbo].[Students] ([Name], [ID], [Sex]) VALUES (N'趙六', 4, 0) SET IDENTITY_INSERT [dbo].[Students] OFF USE [master] GO ALTER DATABASE [MyStudy] SET READ_WRITE GO
對於列傳行我們參考《T-SQL基礎教程》中提供的方式
方法1:

WITH CTE AS ( SELECT tab3.Name , tab2.CourseName , tab1.Number FROM dbo.ScoreAndCourse tab1 LEFT JOIN dbo.Course tab2 ON tab2.ID = tab1.CourseID LEFT JOIN dbo.Students tab3 ON tab3.ID = tab1.StudentID ) SELECT tab4.Name , SUM(CASE WHEN tab4.CourseName = '語文' THEN tab4.Number END) AS '語文' , SUM(CASE WHEN tab4.CourseName = '數學' THEN tab4.Number END) AS '數學' , SUM(CASE WHEN tab4.CourseName = '英語' THEN tab4.Number END) AS '英語' , SUM(CASE WHEN tab4.CourseName = '物理' THEN tab4.Number END) AS '物理' , SUM(CASE WHEN tab4.CourseName = '化學' THEN tab4.Number END) AS '化學' FROM CTE tab4 GROUP BY tab4.Name ORDER BY tab4.Name;
方法2:

WITH CTE AS ( SELECT tab3.Name , tab2.CourseName , tab1.Number FROM dbo.ScoreAndCourse tab1 LEFT JOIN dbo.Course tab2 ON tab2.ID = tab1.CourseID LEFT JOIN dbo.Students tab3 ON tab3.ID = tab1.StudentID ) SELECT p.Name , 語文 , 數學 , 英語 , 物理 , 化學 FROM CTE AS base1 PIVOT ( SUM(Number) FOR CourseName IN ( 語文, 數學, 英語, 物理, 化學 ) ) AS p;
注釋:
1. CTE:公用表表達式
2.PIVOT:運算符(與之相反的 UNPIVOT )