Sql 透视表中的文本值?
我有一个表(在MySQL中),有3列: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
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不开箱即用!?