关于SQL中PIVOT函数的使用方法

img

img


如果我想将图1中通过union拼接完成的查询结果表转换为图2的表SQL我应该怎么写

你可以看看我们得官方文档:https://learn.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-ver16
这种需求unpivot是实现不了的,unpivot的使用有很多限制,你的字段类型都不能保障是一样的,何况还是多union出来的联合查询结果,想想其他办法吧

该回答引用chatgpt
参考如下写法
在 SQL 中,PIVOT 函数可以用于将行数据转换为列数据。它对于进行交叉表格查询非常有用。以下是一个使用 PIVOT 函数的示例:

假设你有一个名为 sales 的表,包含以下数据:

+-------+-------+-------+---------+
| Month | Apple | Banana|  Orange |
+-------+-------+-------+---------+
|   Jan |   100 |   200 |     150 |
|   Feb |   120 |   220 |     180 |
|   Mar |   90  |   180 |     120 |
+-------+-------+-------+---------+

要将月份作为列,水果作为行,并显示每个月份的水果销售量,可以使用 PIVOT 函数进行转换。

SELECT *
FROM (
  SELECT Month, Fruit, Quantity
  FROM sales
) AS src
PIVOT (
  SUM(Quantity)
  FOR Month IN ([Jan], [Feb], [Mar])
) AS pvt;

在上面的示例中,我们首先从 sales 表中选择 MonthFruitQuantity 列,并将其作为子查询的结果。然后,我们使用 PIVOT 函数将 Month 列的值作为新的列名,并对 Quantity 列进行求和操作。最后,我们将结果命名为 pvt 表。

执行上述查询后,将获得以下结果:

+--------+-----+-----+-----+
| Fruit  | Jan | Feb | Mar |
+--------+-----+-----+-----+
| Apple  | 100 | 120 |  90 |
| Banana | 200 | 220 | 180 |
| Orange | 150 | 180 | 120 |
+--------+-----+-----+-----+

可以看到,原始的行数据已经被转换为以月份为列的交叉表格形式。

请注意,PIVOT 函数的具体语法可能因不同的数据库而有所不同。上述示例使用的是通用的 SQL 语法,但某些数据库可能具有特定的 PIVOT 函数实现。在实际使用时,请参考你所使用的数据库的文档以了解更多详细信息。

就你发出来的内容来看呢,并不适合使用行列转换,因为你的目标列并不固定,应该考虑把数据查询出来后在程序中进行处理

http://t.csdn.cn/iA6Kb

借鉴下 https://www.cnblogs.com/zoro-zero/p/11334785.html

照着这个文档来就行

SELECT <non-pivoted column>,  
    [first pivoted column] AS <column name>,  
    [second pivoted column] AS <column name>,  
    ...  
    [last pivoted column] AS <column name>  
FROM  
    (<SELECT query that produces the data>)   
    AS <alias for the source query>  
PIVOT  
(  
    <aggregation function>(<column being aggregated>)  
FOR   
[<column that contains the values that will become column headers>]   
    IN ( [first pivoted column], [second pivoted column],  
    ... [last pivoted column])  
) AS <alias for the pivot table>  
<optional ORDER BY clause>;  

如果不是必须用PIVOT这个函数,
我教你这样写,列转行也可以用union all来表示

with t1 as (
SELECT * from test where 题目 like '%李白%'
union all
SELECT * from test where 题目 like '%人造卫星%'  
)
select 题目 from t1
union all
select 正确答案 from t1
union all 
select 正确选项 from t1;

sql中PIVOT 用法详解可以参考:
sql中PIVOT 用法详解:https://www.cnblogs.com/feiyublog/archive/2011/07/11/2103116.html
但是不一定实现的了。如果不行,可以考虑使用sql查询出来后再代码中进行处理。

PIVOT 函数是用于将行数据转换为列数据

SQL中PIVOT的用法_sql pivot_weixin_43715545的博客-CSDN博客 PIVOT 提供的语法比一系列复杂的 SELECT…CASE 语句中所指定的语法更简单和更具可读性。以下是带批注的 PIVOT 语法:SELECT <非透视的列>, [第一个透视的列] AS <列名称>, [第二个透视的列] AS <列名称>, ... [最后一个透视的列] AS <列名称>,FROM (..._sql pivot https://blog.csdn.net/weixin_43715545/article/details/102636774?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522169105715916800225576949%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=169105715916800225576949&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-4-102636774-null-null.142^v92^controlT0_1&utm_term=%E5%85%B3%E4%BA%8ESQL%E4%B8%ADPIVOT%E5%87%BD%E6%95%B0%E7%9A%84%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95&spm=1018.2226.3001.4187

行列转置可以用PIVOT 函数

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这篇博客: Oracle 行转列 pivot函数基本用法中的 四、pivot进行转换的SQL(查询结果就是上面的结果图) 部分也许能够解决你的问题。
  • 以下回答由chatgpt基于相关博客总结生成:

    回答:

    要实现图2所示的目标表格格式,可以使用SQL中的PIVOT函数来完成。以下是具体的解决方案。

    首先,需要使用UNION拼接完成的查询结果表作为子查询,并对其进行列转行的操作。然后,使用PIVOT函数将转换后的结果表按照指定的格式进行展示。

    具体步骤如下:

    1. 将通过UNION拼接的查询结果表作为子查询,并给每个子查询添加一个标识列,以区分不同的查询结果。例如:
    SELECT 1 AS id, column1 AS code FROM table1
    UNION ALL
    SELECT 2 AS id, column2 AS code FROM table2
    UNION ALL
    SELECT 3 AS id, column3 AS code FROM table3
    
    1. 对子查询结果表进行列转行,将每个查询结果作为一个单独的列,并将结果存储到一个新的表中。例如:
    SELECT id, 
           MAX(CASE WHEN seq = 1 THEN code END) AS code1,
           MAX(CASE WHEN seq = 2 THEN code END) AS code2,
           MAX(CASE WHEN seq = 3 THEN code END) AS code3
    FROM (
        SELECT id,
               code,
               ROW_NUMBER() OVER (PARTITION BY id ORDER BY id) AS seq
        FROM (
            SELECT 1 AS id, column1 AS code FROM table1
            UNION ALL
            SELECT 2 AS id, column2 AS code FROM table2
            UNION ALL
            SELECT 3 AS id, column3 AS code FROM table3
        ) t
    ) t
    GROUP BY id
    
    1. 最后,根据需要对结果表进行进一步的处理和排序,以满足目标表格格式的要求。例如:
    SELECT id, code1, code2, code3
    FROM (
        SELECT id, 
               MAX(CASE WHEN seq = 1 THEN code END) AS code1,
               MAX(CASE WHEN seq = 2 THEN code END) AS code2,
               MAX(CASE WHEN seq = 3 THEN code END) AS code3
        FROM (
            SELECT id,
                   code,
                   ROW_NUMBER() OVER (PARTITION BY id ORDER BY id) AS seq
            FROM (
                SELECT 1 AS id, column1 AS code FROM table1
                UNION ALL
                SELECT 2 AS id, column2 AS code FROM table2
                UNION ALL
                SELECT 3 AS id, column3 AS code FROM table3
            ) t
        ) t
        GROUP BY id
    ) t
    ORDER BY id
    

    以上是使用SQL中的PIVOT函数将通过UNION拼接的查询结果表转换成目标表格格式的具体步骤和示例代码。如果以上的解决方案不能满足您的需求,请提供更详细的信息和样例数据,以便我能够给出更准确的帮助。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

PIVOT函数用于将表中的列换成行。它可以将表达式中的一个列的唯一值转换为输出中的多列,来轮替表值表达式。PIVOT在需要对最终输出所需的所有剩余列值执行聚合时运行聚合。与PIVOT 执行的操作相反,UNPIVOT 将表值表达式的列轮换为列值。PIVOT的语法比一系列复杂的 SELECT…CASE 语句中指定的语法更简单、更具可读性。

例如,下面是一个简单的 PIVOT 示例:

SELECT 'AverageCost' AS Cost_Sorted_By_Production_Days,
[0], [1], [2], [3], [4]
FROM
(SELECT DaysToManufacture, StandardCost
FROM Production.Product) AS SourceTable
PIVOT
(
AVG(StandardCost)
FOR DaysToManufacture IN ([0], [1], [2], [3], [4])
) AS PivotTable;

在SQL中,PIVOT函数是一种常用的转换数据集的工具。它可以将一列数据旋转成行,并将行数据转换为列数据,从而实现数据的透视。PIVOT函数可以帮助人们更好地理解数据并进行分析。本文将详细介绍SQL中PIVOT函数的使用方法。

1. PIVOT函数的语法

SQL中PIVOT函数的语法如下:

SELECT <non-pivoted column>, [first pivoted column] AS <column name>, 
[second pivoted column] AS <column name>, ...
FROM <table name>
PIVOT (<aggregation function>(<value column>)
FOR <column name> IN ([first pivoted column], [second pivoted column], ...)) AS <alias name>

其中,

  • <non-pivoted column>:非旋转列,即不需要转置的列。
  • first pivoted column, second pivoted column, ...:需要旋转的列。
  • <column name>:旋转列在输出结果中的列名,可以自定义。
  • <aggregation function>:汇总函数,可以是SUM、COUNT、AVG等。
  • <value column>:需要进行汇总的列的列名。
  • <table name>:查询的数据表名。
  • <alias name>:输出结果表的别名。

2. PIVOT函数的应用

下面给出一个例子,说明如何使用PIVOT函数将一列数据旋转成行。假设我们有一个名为Sales的销售数据表,其中包含了销售人员的姓名、销售日期和销售额。我们想要将它们旋转成一张表格,显示每个销售人员在每个月的销售额。可以使用下面的SQL语句:

SELECT *
FROM
(
  SELECT Salesperson, MONTH(SalesDate) AS Month, SalesAmount
  FROM Sales
) t
PIVOT
(
  SUM(SalesAmount) FOR Month IN ([1], [2], [3], [4], [5], [6], 
  [7], [8], [9], [10], [11], [12])
) AS pivot_table;

这个SQL语句的结果如下:

Salesperson123456789101112
Jack4522.43866.57898.55467.26178.48890.54199.15987.65689.23938.17290.57811.3
Mike3473.26889.25411.54589.97452.17890.15678.37546.25682.44356.28999.36001.2
Tom6689.55432.14589.57890.33212.66743.95300.14312.44567.26789.36543.57890.4

这个结果表格的列是每个月,行是每个销售人员,其中的数值是每个销售人员在每个月的销售额。

使用PIVOT函数时,需要注意以下几点:

  • PIVOT函数中的列必须是可以进行聚合计算的列;
  • 子查询中的列名需要与PIVOT函数中的列名相同;
  • 需要指定每个旋转列的列名及其在输出结果中的列名;
  • 如果数据表中没有数据满足PIVOT函数的条件,则输出的结果中会缺少该列。

3. 使用PIVOT函数进行多重统计

除了将单列数据旋转成行,PIVOT函数还可以用于多重统计。例如,在上述例子中,我们还想要计算每个销售人员的总销售额和年度销售额。可以使用下面的SQL语句:

SELECT Salesperson, 
[1] AS Jan, [2] AS Feb, [3] AS Mar, [4] AS Apr, [5] AS May, [6] AS Jun, 
[7] AS Jul, [8] AS Aug, [9] AS Sep, [10] AS Oct, [11] AS Nov, [12] AS Dec,
ISNULL([1],0)+ISNULL([2],0)+ISNULL([3],0)+ISNULL([4],0)+ISNULL([5],0)
+ISNULL([6],0)+ISNULL([7],0)+ISNULL([8],0)+ISNULL([9],0)+ISNULL([10],0)
+ISNULL([11],0)+ISNULL([12],0) AS TotalSales,
ISNULL([1],0)+ISNULL([2],0)+ISNULL([3],0)+ISNULL([4],0)+ISNULL([5],0)
+ISNULL([6],0)+ISNULL([7],0)+ISNULL([8],0)+ISNULL([9],0)+ISNULL([10],0)
+ISNULL([11],0)+ISNULL([12],0) AS AnnualSales
FROM
(
  SELECT Salesperson, MONTH(SalesDate) AS Month, SalesAmount
  FROM Sales
) t
PIVOT
(
  SUM(SalesAmount) FOR Month IN ([1], [2], [3], [4], [5], [6], 
  [7], [8], [9], [10], [11], [12])
) AS pivot_table;

这个SQL语句的结果如下:

SalespersonJanFebMarAprMayJunJulAugSepOctNovDecTotalSalesAnnualSales
Jack4522.43866.57898.55467.26178.48890.54199.15987.65689.23938.17290.57811.373859.373859.3
Mike3473.26889.25411.54589.97452.17890.15678.37546.25682.44356.28999.36001.275719.675719.6
Tom6689.55432.14589.57890.33212.66743.95300.14312.44567.26789.36543.57890.472701.872701.8

这个结果表格中,除了每个销售人员每个月的销售额外,还包含了每个销售人员的总销售额和年度销售额。

4. 结论

在SQL中,PIVOT函数是一种非常有用的工具,可以在数据透视、数据分析等方面发挥重要作用。本文针对PIVOT函数的语法和使用方法进行了详细介绍,希望读者可以通过本文学习到PIVOT函数的基本操作和使用技巧。

在SQL中,PIVOT函数是一种非常有用的数据转换函数,它可以将行转换为列,将列转换为行,从而方便地进行数据分析。

PIVOT函数的基本语法如下:

SELECT *
FROM (
    SELECT <aggregate function>(<value column>) AS <aggregate expression>, <column1>, <column2>
    FROM <table>
    GROUP BY <column1>, <column2>
) AS <source table>
PIVOT (
    <aggregate function>(<aggregate expression>)
    FOR <column> IN ([<value1>], [<value2>], …, [<valueN>])
) AS <pivot table>

其中,是聚合函数(如SUM、AVG、MAX等),是需要聚合的列名,是聚合函数的结果别名(可以自定义),和是需要分组的列名。

在PIVOT函数中,需要指定要转换的列名,列名包含在FOR子句中。IN子句用于指定列名对应的值,值用方括号括起来,多个值用逗号分隔。

PIVOT函数的执行过程如下:

  1. 执行内部SELECT语句,并按和进行分组,然后进行聚合计算,生成一个结果集。

  2. 将分组后的结果集转换成一个临时表(也称为源表),该表包含分组列(和)、聚合列()和值列(和FOR子句中指定的列名相同)。

  3. 对源表进行PIVOT操作,根据FOR子句中指定的列名将值列转换成列名,并对聚合列进行聚合计算,生成一个新的表(也称为目标表)。

下面是一个示例,假设有一个销售数据表sales:

product | month | sales
--------|-------|-------
A       | Jan   | 100
A       | Feb   | 200
B       | Jan   | 150
B       | Feb   | 250

要将月份作为列名,产品作为行名,查看销售额,可以使用PIVOT函数:

SELECT *
FROM (
    SELECT SUM(sales) AS total_sales, product, month
    FROM sales
    GROUP BY product, month
) AS source_table
PIVOT (
    SUM(total_sales)
    FOR month IN ([Jan], [Feb])
) AS pivot_table

执行结果如下:

product | Jan  | Feb
--------|-----|-----
A       | 100 | 200
B       | 150 | 250

可以看到,PIVOT函数将月份行转换为列,将产品列转换为行,从而方便地进行数据分析。

需要注意的是,PIVOT函数只适用于固定列数的情况,如果列数是不确定的,可以使用动态PIVOT或UNPIVOT函数来处理。