2017-03-14 91 views
2

我想請求獲得幫助我解決當前困境的SELECT語句的幫助。我正在使用SQL Server在vb.net上創建一個新項目,我的僱主希望我創建的其中一個報告是使用他們給我的excel文件中的數據獲取所需的部分名稱和數量,但是,它的工作原理與這樣的:如何選擇列名稱並獲取SQL Server的數據?

Sample Table

的數據實際上比這個(如200個+部分)放大了很多,但這是一般的想法。我將有DWG名進入它,我想一​​個SELECT,將有一個這樣的輸出:

(如果用戶是通過DWG1 :)

DWG1  1 Part3 
DWG1  2 Part4 
DWG1  1 Part5 

去,是有辦法搶只有那些數字大於0的列名稱,才能得到確切的數字,然後是那個列名稱?我不認爲給我Excel文件的人有正確的表格結構。

+1

您正在使用哪些DBMS? mysql <> sql服務器。你能否嘗試清楚地解釋你想要完成的事情?從你張貼的照片來看,對我來說毫無意義。 –

+0

這看起來像您可能想要使用UNPIVOT,但很難理解您真正想要的內容。 –

+0

對不起,SQL Server。該網站只是自動踢它到MySQL。基本上,在行的開始處給出一個值,我想要遍歷整行,並選取大於0的任何值,如果這些值大於0,我需要獲取它們所在的列名。 –

回答

1

UNPIVOT將是更好的性能,但是如果你請勿要指定200場,考慮一下:

Declare @YourTable table (DWG varchar(25),Part1 int,Part2 int,Part3 int,Part4 int,Part5 int) 
Insert into @YourTable values 
('DWG1',0,0,1,2,1), 
('DWG2',0,0,0,0,1) 

Select C.* 
    From @YourTable A 
    Cross Apply (Select XMLData=cast((Select A.* for XML RAW) as xml)) B 
    Cross Apply (
       Select DWG = r.value('@DWG','varchar(25)')    --<< case sensitive 
         ,Item = attr.value('local-name(.)','varchar(100)') 
         ,Value = attr.value('.','varchar(max)')    --<< can be int if desired 
       From B.XMLData.nodes('/row') as A(r) 
       Cross Apply A.r.nodes('./@*') as B(attr) 
       Where attr.value('local-name(.)','varchar(100)') not in ('DWG','OtherFieldsToExclude') 
      ) C 
    --Where A.DWG='DWG1' 

返回

DWG  Item Value 
DWG1 Part1 0 
DWG1 Part2 0 
DWG1 Part3 1 
DWG1 Part4 2 
DWG1 Part5 1 
DWG2 Part1 0 
DWG2 Part2 0 
DWG2 Part3 0 
DWG2 Part4 0 
DWG2 Part5 1 
+0

這看起來很棒。感謝代碼! –

+0

@ C.Clements對它有幫助,我相信你會看到它的表現是值得尊敬的。 :) –

+0

@ C.Clements爲了記錄,它被稱爲EAV結構(實體屬性值)。處理寬泛和/或多變的表格時非常有用 –

1

從電子表格開始與此數據:

enter image description here

我用一個小程序從電子表格文件,並輸出到讀取數據,你發現:

Option Infer On 
Option Strict On 

Imports System.Data.OleDb 

Module Module1 

    Class Part 
     Property Name As String 
     Property Quantity As Decimal 

     Public Overrides Function ToString() As String 
      Return $"{Name}: {Quantity}" 
     End Function 

    End Class 

    Class Dwg 
     Property Name As String 
     Property Parts As List(Of Part) 

     Public Overrides Function ToString() As String 
      Return $"{Name} - {String.Join(", ", Parts)}" 
     End Function 

    End Class 

    Sub Main() 
     Dim xlFile = "C:\temp\PartsList.xlsx" 
     Dim connStr = $"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={xlFile};Extended Properties=""Excel 12.0 Xml;HDR=YES"";" 

     Dim dt As New DataTable 

     Using conn = New OleDbConnection(connStr) 
      Dim qry = "SELECT * FROM [Sheet1$]" 
      Using da = New OleDbDataAdapter(qry, conn) 
       da.Fill(dt) 
      End Using 
     End Using 

     ' To show the column names... 
     'For Each col As DataColumn In dt.Columns 
     ' Console.WriteLine(col.ColumnName) 
     'Next 

     Dim dwgs As New List(Of Dwg) 

     ' Read the data into a list... ' 
     For i = 0 To dt.Rows.Count - 1 
      Dim dx As New Dwg With {.Name = CStr(dt.Rows(i)(0))} 
      Dim parts As New List(Of Part) 
      For j = 1 To dt.Columns.Count - 1 
       Dim qty = CDec(dt.Rows(i)(j)) 
       If qty <> 0 Then 
        parts.Add(New Part With {.Name = dt.Columns(j).ColumnName, .Quantity = qty}) 
       End If 
      Next 
      dx.Parts = parts 
      dwgs.Add(dx) 
     Next 

     ' Show all the data read... ' 
     Console.WriteLine("ALL DWGS:-") 
     For Each d As Dwg In dwgs 
      Console.WriteLine(d.ToString()) 
     Next 
     Console.WriteLine() 

     ' Show the data from a selected item... ' 
     Dim selectedDwg = "DWG1" 

     Console.WriteLine($"Drawing {selectedDwg}:-") 
     Dim dw = dwgs.First(Function(x) x.Name = selectedDwg) 

     If dw IsNot Nothing Then 
      For Each p In dw.Parts 
       Console.WriteLine($"{dw.Name,-10}{p.Quantity,-8}{p.Name,-12}") 
      Next 
     End If 

     Console.ReadLine() 

    End Sub 

End Module 

輸出:

ALL DWGS:- 
DWG1 - Sprocket: 1, Widget: 2, Part 5: 1 
DWG2 - Part 5: 1 
DWG3 - Part 1: 1, Sprocket: 2, Widget: 1 

Drawing DWG1:- 
DWG1  1  Sprocket 
DWG1  2  Widget 
DWG1  1  Part 5 

一旦你在程序中的數據,可以很容易地使用適當的模式將其插入到SQL Server等數據庫中。

[我沒有使用Excel來創建電子表格 - 我用的LibreOffice Calc中,並將其保存爲xlsx檔案,我必須安裝Microsoft Access數據庫引擎2010可再發行組件的連接字符串中的供應商。]

相關問題