Sql 是否在Access中的一个字段中连接多行?
可能重复:Sql 是否在Access中的一个字段中连接多行?,sql,ms-access,Sql,Ms Access,可能重复: 我有一个表,它有许多列,但有两个有趣的列:订单号和产品类型。目前,表中每个订单有多个产品类型。如果客户订购了电话服务、电视服务和互联网服务,则会有三条记录——每项服务一条记录,但所有记录的订单号都相同。我想创建一个引用表来存储包含客户订购的所有服务的连接字符串。这样,我就可以用这种更符合逻辑的方法总结我的数据。我使用的是标准的Access 2010数据库 **Current table:** Order Number | Product Types 100001 | TV 1
我有一个表,它有许多列,但有两个有趣的列:订单号和产品类型。目前,表中每个订单有多个产品类型。如果客户订购了电话服务、电视服务和互联网服务,则会有三条记录——每项服务一条记录,但所有记录的订单号都相同。我想创建一个引用表来存储包含客户订购的所有服务的连接字符串。这样,我就可以用这种更符合逻辑的方法总结我的数据。我使用的是标准的Access 2010数据库
**Current table:**
Order Number | Product Types
100001 | TV
100001 | Phone
100001 | Internet
100002 | Phone
100003 | TV
100003 | Internet
所需参考表
100001 | TV/Phone/Internet
100002 | Phone
100003 | TV/Internet
不应创建连接记录的引用表。这就是数据库的非规范化
**Current table:**
Order Number | Product Types
100001 | TV
100001 | Phone
100001 | Internet
100002 | Phone
100003 | TV
100003 | Internet
您可以尝试下面这样的交叉表查询,但我尚未对其进行测试。你可以查询更多信息
TRANSFORM First([Product Types]) AS Product
SELECT [Order Number], First([Product Types])
FROM CurrentTable
GROUP [Order Number]
Allen Browne提供了一个函数,您可能会发现该函数对此有用:。将该函数的代码保存在标准模块中
SELECT DISTINCT
[Order Number],
ConcatRelated("[Product Types]",
"YourTable",
"[Order Number] = " & [Order Number],
"[Product Types]",
"/"
) AS All_Product_Types
FROM YourTable;
我在Access 2007中使用保存在名为“YourTable”的表中的示例数据测试了该查询。它返回了您要求的结果。但是,这只在访问会话中起作用。如果要从外部访问(如从ASP)运行此查询,则用户定义的函数不可用,因此您将得到一个关于ConcatRelated()
无法识别的错误
因此,您可以随时使用查询检索连接的值。但是,如果存储这些连接的值,它们可能很快与基表数据的更改不同步 如果我理解这个问题,你是在问如何获得那些拥有电视、电话和互联网的订单的订单号。如果您对这些订单号感兴趣,可以运行如下查询:
SELECT Distinct Table1.OrderNumber
FROM (Select OrderNumber from Table1 where [product types]= "Internet") AS i
INNER JOIN ((Select OrderNumber from Table1 where [product types]="Phone") AS p
INNER JOIN ((Select OrderNumber from Table1 Where [product types]= "TV") AS tv
INNER JOIN Table1 ON tv.OrderNumber = Table1.OrderNumber) ON p.OrderNumber = Table1.OrderNumber) ON i.OrderNumber = Table1.OrderNumber;
正如onedaywhen在关于SO的早期帖子中指出的,使用ADO更容易做到: 示例查询:
SELECT [Order Number],
ConcatADO("SELECT [Product Types] FROM Orders
WHERE [Order Number]=" & [Order Number],", "," : ") AS Cat
FROM Orders
GROUP BY [Order Number], 2;
函数使用ADO
Function ConcatADO(strSQL As String, strColDelim, _
strRowDelim, ParamArray NameList() As Variant)
Dim rs As New ADODB.Recordset
Dim strList As String
On Error GoTo Proc_Err
If strSQL <> "" Then
rs.Open strSQL, CurrentProject.Connection
strList = rs.GetString(, , strColDelim, strRowDelim)
strList = Mid(strList, 1, Len(strList) - Len(strRowDelim))
Else
strList = Join(NameList, strColDelim)
End If
ConcatADO = strList
Exit Function
Proc_Err:
ConcatADO = "***" & UCase(Err.Description)
End Function
函数ConcatADO(strSQL作为字符串,strColDelim_
strRowDelim,ParamArray NameList()作为变量)
将rs设置为新ADODB.Recordset
模糊strList作为字符串
关于错误转到程序错误
如果是strSQL“”,则
打开strSQL,CurrentProject.Connection
strList=rs.GetString(,strColDelim,strRowDelim)
strList=Mid(strList,1,Len(strList)-Len(strRowDelim))
其他的
strList=Join(名称列表,strColDelim)
如果结束
ConcatADO=strList
退出功能
过程错误:
ConcatADO=“***”&UCase(错误描述)
端函数
您不应该这样做。您正在对数据库进行非规范化。有更好的方法吗?最终,我只希望能够在“电视/电话/互联网”级别上进行报告。在演示级别(报告)而不是数据存储级别上进行非规范化我认为您希望这是一个视图
而不是表
。出于报告目的,它将得到相同的结果,但数据将保持在逻辑状态organization@njk如果他所做的只是创建数据视图并将其相应地连接起来,那么他就不会对数据库进行非规范化。对于他为报告目的而构建的表,规范化并不重要。OP不应该是使用非规范化的用于报告目的的表。他可以选择视图
。他没有什么理由不这样做。事实上,在某些情况下,将数据存储在静态、非规范化的表中可能更可取。例如,如果数据变化不大,或者不需要随时更新,他只需每隔一段时间查询其他表一次,而不是每次运行报表时。它还使SQL变得更容易,因为他可以使用多个查询来构建数据集,而不是试图将逻辑压缩到单个查询中。@Jim这不应该在数据库层上完成。