2011-10-12 110 views
2

我有3列的表(在MySQL):數據透視表中的文本值?

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自己工作。

任何想法的?

+0

[這聽起來像你沒有使用很多MS堆棧,所以我把它作爲一個評論,而不是回答。] SQL Server Reporting Services將很好地處理這種情況,併爲您提供出色的Excel輸出。你可以從SSRS查詢MySQL數據庫。但是如果你沒有MS SQL服務器,這是一個不好的選擇。 –

+0

您是否嘗試過使用帶有最大聚合函數的數據透視表? – PowerUser

+0

嘗試過,但不起作用。 – Dylan

回答

0

我也沒有辦法檢查查詢是好的,但或多或​​少會是這樣的查詢:

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 
1

我遇到了同樣的問題,使用數據透視表...完美的總結,但不適用於文本矩陣。

我剛剛「舉起」了一些我使用過的代碼示例。在這裏,我有列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 

代碼示例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 
0

你追求的是什麼通常被稱爲交叉表。這可以靜態地完成像這樣:

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語句,或者使用報告工具來執行相同的操作。