模拟数据:
大多数数据库存储的数据都是这样,但是实际业务则需要我们对数据进行处理如下:
这就是很多时候面试也会遇到的列传行的问题。
创建数据库以及数据:
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 )
来源:oschina
链接:https://my.oschina.net/u/4391746/blog/3945470