簡體   English   中英

使用SQL查詢的UNPIVOT列

[英]UNPIVOT columns using SQL query

我正在拉另一個工作簿,其中包含一個表,該表具有諸如ItemCreationDate之類的列,並且大多數列(總共28列)以“ Global”一詞開頭。 我想要

  1. 將這些“全局”列(包括ItemCreationDate)拉入SQL記錄集,添加一個名為“舊/新”的新列,然后
  2. 取消它們,即將它們一個堆疊在另一個之上,然后
  3. 在下一列中,列出其列項目及其計數。
  4. 它們的計數是根據ItemCreationDate導出的,其中任何日期<2015是舊日期,而> = 2015是新日期
  5. 最終輸出應如輸出表中所示。

我已經附加了Sample.xlsx文件,其中顯示了如何從數據表開始到達“輸出”選項卡。 該數據表實際上是我要拉入記錄集並吐出表的輸入,如輸出表所示。 我不想創建數據透視表,因為它麻煩而且數據很多,我想要一種替代的SQL方法,其中我可以快速匯總數據並將其一次性插入到工作表中。

我未使用SQL Server,因此無法使用UNPIVOT命令或動態SQL遍歷所有“全局”列。

基本上我想形成一個正確的SQL字符串之類的...。

Dim arrSQL as variant
......
......
RS.Filter="Like Global*"
......
arrSQL = JOIN(RS.Fields, vbCr)

strSQL = "SELECT [arrSQL], IIF(YEAR([ITEM CREATION DATE])>=YEAR(DATE())-1,""NEW"",""OLD"") AS [New/Old]  from [Data$] GROUP BY...."
strSQL = strSQL & " UNION ALL " & vbcr & _
strSQL = strSQL & " ......

現在,在同一記錄集上運行SQL以減少列並獲取所需的數據格式...。我知道上面的方法不是很正確,但是在那些行上有一些用法,以便我可以得到正確的輸出,如“輸出”選項卡中所示。

誰能迅速提供幫助?

編輯@a_horse_with_no_name:

查看示例文件的屏幕截圖:

  1. 數據表:這實際上是我要插入Recordset的輸入工作簿中的表。 請參閱各種“全局”列標題及其要取消的項目。

在此處輸入圖片說明

  1. 這是我每次都必須創建的兩個中間表“ New”和“ Old”(實際上我想擺脫它們)。 在2015年或以后發現的所有商品都放置在“新”中,而其余商品則放置在“舊”中。

在此處輸入圖片說明

在此處輸入圖片說明

  1. 在此處輸入圖片說明

  2. JFYI,在“輸出”列中手動使用的公式為:

C欄(新):

=COUNTIF(INDEX(New!$A:$D,0,MATCH($A2,New!$1:$1,0)),Output!$B2)

D柱(舊):

=COUNTIF(INDEX(Old!$A:$D,0,MATCH($A2,Old!$1:$1,0)),Output!$B2)

E欄(新百分比):

=Output!C2/SUM(C$2:C$6)

F柱(舊%):

=Output!D2/SUM(D$2:D$6)

G欄(索引):

=IF(AND(E2<=0,F2<=0),0,IF(AND(E2>0,F2>0),E2/F2,1))

希望這可以幫助。

確實,您可以使用Jet / ACE SQL引擎 (Windows .dll文件)在MS Excel中運行SQL查詢,這是默認情況下MS Access連接到的數據存儲。 因此,所有PC上配備的這項技術並不限於任何一個Office / Windows程序。

考慮下面的Excel VBA宏(如果在PC上使用Excel)(如果在PC上使用Excel),則通過運行三個聚合SQL查詢( GLOBAL VIT / CALCGLOBAL FLAVORSGLOBAL FLAVOR GROUP )以及有條件的新舊計數/百分比的並集,通過ADO連接到ACE。 后面的百分比列對需要子查詢。

為了進行正確的設置,請執行以下操作:

  1. 確保“ Item Creation Date采用MM-DD-YYYY(基於美國)或DD-MM-YYYY(非基於美國)的日期格式,而不是上面的屏幕快照或文件當前具有日期格式的日期格式。

    Sub FormatDates() For i = 2 To 2083 Range("A" & i) = CDate(Range("A" & i)) Next i End Sub

  2. 在與保存數據的工作簿不同的另一工作簿中運行宏。 下面假設數據工作簿在名為Data工作表中保存源信息。

  3. 在運行查詢的工作簿中,創建一個名為RESULTS的空白工作表,該工作表將填充包含列標題的查詢輸出。

VBA腳本(兩個連接可用的驅動程序(已注釋)和提供程序版本)

Option Explicit

Sub RunSQL()
    Dim cols As Object, datawbk As Workbook, datawks As Worksheet
    Dim lastcol As Integer, i As Integer, j As Variant, output As Variant

    Set cols = CreateObject("Scripting.Dictionary")
    Set datawbk = Workbooks.Open("C:\Path\To\Data\Workbook.xlsx;")
    Set datawks = datawbk.Worksheets("Data")
    lastcol = datawks.Cells(7, datawks.Columns.Count).End(xlToLeft).Column

    For i = 2 To lastcol
         cols.Add CStr(i - 1), datawks.Cells(1, i).Value
    Next i

    datawbk.Close False
    Set datawks = Nothing
    Set datawbk = Nothing

    output = DataCapture(cols)

End Sub

Function DataCapture(datacols As Object)
On Error GoTo ErrHandle
    Dim conn As Object, rst As Object
    Dim strConnection As String
    Dim classSQL As String, itemSQL As String, grpSQL As String, strSQL As String
    Dim i As Integer, fld As Object, d As Variant, lastrow As Integer

    Set conn = CreateObject("ADODB.Connection")
    Set rst = CreateObject("ADODB.Recordset")

    ' Hard code database location and name '
'    strConnection = "DRIVER={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};" _
'                      & "DBQ=C:\Path\To\Data\Workbook.xlsx;"
    strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;" _
                       & "Data Source='C:\Path\To\Data\Workbook.xlsx;" _
                       & "Extended Properties=""Excel 12.0 XML;HDR=YES IMEX=1;"";"

    ' OPEN DB CONNECTION '
    conn.Open strConnection

    For Each d In datacols.keys
        strSQL = " SELECT '" & datacols(d) & "' AS [COLUMN], [Data$].[" & datacols(d) & "] AS ITEMS," _
                    & "   SUM(IIF(Year([Item Creation Date]) >= Year(Date()) - 1, 1, 0)) AS NEW," _
                    & " " _
                    & "   SUM(IIF(Year([Item Creation Date]) < Year(Date()) - 1, 1, 0)) AS OLD," _
                    & " " _
                    & "   ROUND(SUM(IIF(Year([Item Creation Date]) >= Year(Date()) - 1, 1, 0)) / " _
                    & "   (SELECT Count(*) FROM [Data$] AS sub" _
                    & "    WHERE Year(sub.[Item Creation Date]) >= Year(Date()) - 1),2) AS NEWPCT," _
                    & " " _
                    & "   ROUND(SUM(IIF(Year([Item Creation Date]) < Year(Date()) - 1, 1, 0)) / " _
                    & "   (SELECT Count(*) FROM [Data$] AS sub" _
                    & "    WHERE Year(sub.[Item Creation Date]) < Year(Date()) - 1),2) AS OLDPCT" _
                    & " FROM [Data$]" _
                    & " GROUP BY [Data$].[" & datacols(d) & "]"

        ' OPEN RECORDSET '
        rst.Open strSQL, conn

        ' COLUMN HEADERS '
        If d = 1 Then
            i = 0
            Worksheets("RESULTS").Range("A1").Activate
            For Each fld In rst.Fields
                ActiveCell.Offset(0, i) = fld.Name
                i = i + 1
            Next fld
        End If

        ' DATA ROWS '
        lastrow = Worksheets("RESULTS").Cells(Worksheets("RESULTS").Rows.Count, "A").End(xlUp).Row
        Worksheets("RESULTS").Range("A" & lastrow + 1).CopyFromRecordset rst

        rst.Close
    Next d

    conn.Close

    MsgBox "Successfully processed SQL query!", vbInformation
    Exit Function

ErrHandle:
    MsgBox Err.Number & " - " & Err.Description, vbCritical
    Exit Function
End Function

輸出量

Excel SQL查詢輸出屏幕截圖

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM