Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 透视表中的文本值?_Sql_Excel_Matrix_Pivot Table - Fatal编程技术网

Sql 透视表中的文本值?

Sql 透视表中的文本值?,sql,excel,matrix,pivot-table,Sql,Excel,Matrix,Pivot Table,我有一个表(在MySQL中),有3列: Location Category Supplier A Computers Company X A Printers Company Y B Computers Company X B Printers Company Y B Software Company Y C Computer

我有一个表(在MySQL中),有3列:

Location    Category     Supplier

   A        Computers    Company X
   A        Printers     Company Y
   B        Computers    Company X
   B        Printers     Company Y
   B        Software     Company Y
   C        Computers    Company Y
   C        Software     Company Z
现在我需要制作一个包含上述信息的矩阵,如下所示:

       Computers      Printers       Software

A      Company X      Company Y
B      Company X      Company Y      Company Y
C      Company Y                     Company Z
最终,我需要在Excel中使用它

事实上,我有一个可变数量的类别,所以在MySQL中为每一列创建一个连接不是一个好的选择。我可以用PHP编写函数,但我想知道是否有更优雅的解决方案

我在Excel中查看了数据透视表,但它们似乎更适合将数字作为值。但也许我忽略了一些东西,因为我从来没有和Excel一起工作过


有什么想法吗?

我无法检查该查询是否正确,但大致是这样的查询:

SELECT t1.Location, MAX(t1.Computers), MAX(t1.Printers),  MAX(t1.Software)

FROM (
SELECT
 t.Location,
 CASE WHEN t.Category = 'Computers' THEN
   t.Supplier
 END Computers,

 CASE WHEN t.Category = 'Printers' THEN
   t.Supplier
 END Printers,

 CASE WHEN t.Category = 'Software' THEN
   t.Supplier
 END Software,
FROM
YOUR_TABLE t
) t1
GROUP BY t1.Location

我在pivot表中遇到了同样的问题。。。非常适合摘要,但不适合文本矩阵

我刚刚“摘取”了一些我使用的代码示例。这里我有A-D列中的数据,并围绕F列构建矩阵(在同一张表中)

检查一下这是否有帮助

我仍然很难让代码看起来正确,所以请注意,很多代码都是在代码窗口之前启动的

代码示例1:

'Fill in the values

Sheets("TempFile").Select

ListRow = 1

MisMatchCounter = 0

Do Until Cells(ListRow, 1).Value = ""

    ' Get table entry from third column of list.

    TableEntry = Cells(ListRow, 3).Value

    On Error Resume Next

    If Err.Number > 0 Then MsgBox Err.Number

    ' Get position of product name within range of row titles.

    If TableEntry <> "" Then

        TableRow = Application.Match(Cells(ListRow, 1), Range("F3:" & MYLastRowAddress), 0) ' 2 rows less than reality

        ' Get position of product size within range of column titles.

        TableColumn = Application.Match(Cells(ListRow, 2), Range("G2:" & MYLastColAddress), 0)

        Set CellToFill = Range("F2").Offset(TableRow, TableColumn)

        ' If there's already an entry in the cell, separate it from the new entry with a comma and space.

        If Err.Number = 0 Then

            If CellToFill.Value <> "" Then

                CellToFill.Value = CellToFill.Value & ","

                CellToFill.Value = CellToFill.Value & TableEntry

            Else

                CellToFill.Value = TableEntry

            End If

        Else

            MisMatchCounter = MisMatchCounter + 1

            Sheets("Errors").Cells(MisMatchCounter, 1).Value = ListRow

            Sheets("Errors").Cells(MisMatchCounter, 2).Value = Cells(ListRow, 1)

            Sheets("Errors").Cells(MisMatchCounter, 3).Value = Cells(ListRow, 2)

            Sheets("Errors").Cells(MisMatchCounter, 4).Value = Cells(ListRow, 3)

            Sheets("Errors").Cells(MisMatchCounter, 5).Value = Cells(ListRow, 4)

        End If

    End If

    On Error GoTo 0

    ListRow = ListRow + 1

Loop
”填写值
工作表(“临时文件”)。选择
ListRow=1
不匹配计数器=0
直到单元格(ListRow,1)为止。Value=“”
'从列表的第三列获取表项。
TableEntry=单元格(ListRow,3).值
出错时继续下一步
如果错误号>0,则MsgBox错误号
'获取行标题范围内产品名称的位置。
如果表条目为“”,则
TableRow=Application.Match(单元格(ListRow,1),范围(“F3:”&MyAstrowAddress),0)比实际值少2行
'获取产品大小在列标题范围内的位置。
TableColumn=Application.Match(单元格(ListRow,2),范围(“G2:”&MYLastColAddress),0)
设置CellToFill=范围(“F2”).偏移量(TableRow,TableColumn)
'如果单元格中已有条目,请用逗号和空格将其与新条目分开。
如果Err.Number=0,则
如果CellToFill.Value为“”,则
CellToFill.Value=CellToFill.Value&“
CellToFill.Value=CellToFill.Value&TableEntry
其他的
CellToFill.Value=TableEntry
如果结束
其他的
错配计数器=错配计数器+1
工作表(“错误”)。单元格(不匹配计数器,1)。值=列表行
表格(“错误”)。单元格(不匹配计数器,2)。值=单元格(列表行,1)
表格(“错误”)。单元格(不匹配计数器,3)。值=单元格(列表行,2)
表格(“错误”)。单元格(不匹配计数器,4)。值=单元格(列表行,3)
表格(“错误”)。单元格(不匹配计数器,5)。值=单元格(列表行,4)
如果结束
如果结束
错误转到0
ListRow=ListRow+1
环
代码示例2:

Sub CreateManualMatrix()

    Dim TableRow, TableColumn As Integer

    Dim TableEntry As String

    Dim CellToFill As Range

    'Sheet is called Lijst

    'Column A is names for top row

    'Column B is names for left column

    'Column C is value for Matrix



    'Matrix Top Row starts at H1

    'Matrix Left Column starts at G2



    MatrixLastColAddress = Range("H1").End(xlToRight).Address

    MatrixLastRow = Range("G65536").End(xlUp).Row

    LijstReadColumn = 3

    LijstCurrentRow = 2 'make 1 if no header is used

    Do Until Sheets("Lijst").Cells(LijstCurrentRow, 1).Value = ""

        ' Get table entry from third column of list.

        TableEntry = Sheets("Lijst").Cells(LijstCurrentRow, LijstReadColumn).Value

        ' Get position of Employee name within Matrix.

        TableColumn = Application.Match(Sheets("Lijst").Cells(LijstCurrentRow, 1), Range("H1:" & MatrixLastColAddress), 0)

        ' Get position of Qualification Name within Matrix titles.

        TableRow = Application.Match(Sheets("Lijst").Cells(LijstCurrentRow, 2), Range("G2:G" & MatrixLastRow), 0)

        Set CellToFill = Range("G1").Offset(TableRow, TableColumn)

        ' If there's already an entry in the cell, separate it from the new entry with a comma and space.

        If CellToFill.Value <> "" Then CellToFill.Value = CellToFill.Value & ","

        ' Add the new entry to the cell.

        CellToFill.Value = CellToFill.Value & TableEntry

        LijstCurrentRow = LijstCurrentRow + 1

    Loop

End Sub
Sub-CreateManualMatrix()
Dim TableRow,TableColumn为整数
Dim TableEntry作为字符串
暗淡的单元格填充为范围
“床单叫Lijst
'列A是最上面一行的名称
'列B是左列的名称
'列C是矩阵的值
'矩阵顶行从H1开始
'矩阵左列从G2开始
MatrixLastColAddress=范围(“H1”).End(xlToRight).Address
MatrixLastRow=范围(“G65536”)。结束(xlUp)。行
LijstReadColumn=3
LijstCurrentRow=2'如果未使用标题,则为1
Do INTIL Sheets(“Lijst”).单元格(LIJSTRENTROW,1)。Value=“”
'从列表的第三列获取表项。
TableEntry=Sheets(“Lijst”).单元格(lijstrentRow,LijstReadColumn).值
'获取员工姓名在矩阵中的位置。
TableColumn=Application.Match(Sheets(“Lijst”).Cells(lijstrentrow,1),Range(“H1:”&MatrixLastColAddress),0)
'获取矩阵标题中资格名称的位置。
TableRow=Application.Match(表(“Lijst”)。单元格(LijstCurrentRow,2),范围(“G2:G”和MatrixLastRow),0)
设置CellToFill=Range(“G1”).偏移量(TableRow,TableColumn)
'如果单元格中已有条目,请用逗号和空格将其与新条目分开。
如果CellToFill.Value为“”,则CellToFill.Value=CellToFill.Value&“
'将新条目添加到单元格中。
CellToFill.Value=CellToFill.Value&TableEntry
LijstCurrentRow=LijstCurrentRow+1
环
端接头

你寻找的东西通常被称为交叉表。这可以静态完成,如下所示:

Select Location
    , Min( Case When Category = 'Computers' Then Supplier End ) As Computers
    , Min( Case When Category = 'Printers' Then Supplier End ) As Printers
    , Min( Case When Category = 'Software' Then Supplier End ) As Software
From MyTable
Group By Location

但是,如果您寻求的是具有动态数量的类别(因此也包括列),那么这不能在SQL中以本机方式完成。后一种解决方案称为动态交叉表。最好的方法是在中间层中构建类似于上面静态版本的SQL语句,或者使用一个报告工具来完成相同的工作。

[听起来您没有使用太多MS堆栈,所以我将此作为一个注释,而不是回答。]SQL Server reporting Services可以很好地处理这种情况,并为您提供出色的Excel输出。您可以从SSRS查询MySQL数据库。但是,如果您没有MS SQL server,这是一个不好的选择。您是否尝试过将pivot表与Max aggregate函数一起使用?尝试过,但不起作用。当我在SSR上尝试时,我得到system.outofmemory异常。。天哪,我只有4列和几千条记录。。我的整套是350000行。宏可以在几分钟内完成。。为什么Excel不开箱即用!?