如何选择列名并为 SQL Server 获取数据?
Posted
技术标签:
【中文标题】如何选择列名并为 SQL Server 获取数据?【英文标题】:How do you select Column Names and grab the data for SQL Server? 【发布时间】:2017-03-14 18:35:27 【问题描述】:我想寻求帮助以获取 SELECT 语句,以帮助我解决当前的困境。我正在使用 SQL Server 在 vb.net 中创建一个新项目,我的雇主希望我创建的报告之一是使用他们给我的 excel 文件中的数据获取所需的零件名称和数量,但是,它的工作方式类似于这个:
数据实际上比这个大很多(比如 200 多个部分),但这是一般的想法。我将在其中输入 DWG 名称,并且我想要一个具有如下输出的 SELECT:
(如果用户使用 DWG1:)
DWG1 1 Part3
DWG1 2 Part4
DWG1 1 Part5
有没有办法只获取其中数字大于 0 的列名,得到确切的数字是什么,然后是那个列名?我认为给我 Excel 文件的人没有考虑到正确的表格结构。
【问题讨论】:
您使用的是哪个 DBMS? mysql sql 服务器。你能试着清楚地解释你想要完成的事情吗?从您发布的图片来看,这对我来说毫无意义。 这看起来你可能想使用 UNPIVOT 但很难理解你真正想要的。 对不起,SQL Server。该站点只是将其自动踢到了 mysql。基本上,给定一行开头的值,我想遍历整行并选择任何大于 0 的值。如果这些值大于 0,我需要获取它们所在的列名。 一次只针对 1 个 DWG,还是全部? 请一次 1 个 DWG。 【参考方案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
【讨论】:
@C.Clements 很高兴它有帮助,我相信你会看到性能是可观的。 :) @C.Clements 为了记录,它被称为 EAV 结构(实体属性值)。在处理广泛和/或变化的表格时非常有帮助【参考方案2】:从包含此数据的电子表格开始:
我使用了一个小程序从电子表格文件中读取数据并按照您显示的方式输出数据:
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,-10p.Quantity,-8p.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 文件,并且我必须在连接字符串中为 Provider 安装 Microsoft Access Database Engine 2010 Redistributable。]
【讨论】:
以上是关于如何选择列名并为 SQL Server 获取数据?的主要内容,如果未能解决你的问题,请参考以下文章