• SQL 行列转换


    模拟数据:

    大多数数据库存储的数据都是这样,但是实际业务则需要我们对数据进行处理如下:

    这就是很多时候面试也会遇到的列传行的问题。

    创建数据库以及数据:

    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:DataMyStudy.mdf' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
     LOG ON 
    ( NAME = N'MyStudy_log', FILENAME = N'E:DataMyStudy_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
    View Code

    对于列传行我们参考《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;
    View Code

    方法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;
    View Code

    注释:

    1. CTE:公用表表达式

    2.PIVOT:运算符(与之相反的 UNPIVOT )

  • 相关阅读:
    Win7下安装iMac系统
    Windows平台cocos2d-x 3.0 android开发环境
    iOS Dev (50)用代码实现图片加圆角
    内部消息 微软中国云计算 内測Azure免费账号 赶紧申请 错过不再有
    android锁屏软件制作
    CF1019E Raining season
    各数据库系统独有函数
    其他函数
    日期时间函数
    字符串函数
  • 原文地址:https://www.cnblogs.com/myloveblogs/p/9148058.html
Copyright © 2020-2023  润新知