考虑这样的一对多关系:
@protocol PublicInterface <NSObject>
@required
- (void)doSomething;
@end
@interface PrivateObject : NSObject<PublicInterface> @end
@implementation PrivateObject
- (void)doSomething {}
@end
@interface Proxy : NSObject
+ (id<PublicInterface>)sharedInstance;
- (instancetype)init NS_UNAVAIALBLE;
@end
@implementation Proxy
- (instancetype)init {
@throw @"Use -sharedInstance instead.";
return nil;
}
+ (id<PublicInterface>)sharedInstance {
static id sharedInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[PrivateObject alloc] init];
});
return sharedInstance;
}
@end
使用这样的一些数据:
tblStuff
- id
tblEntry
- stuff_id
- the_date
- the_value
请注意,对于Stuff#42,有2个连续的条目(1月1日和8日),然后错过一周,然后是另一个条目。
我需要显示每个stuff_id the_date the_value
-------- -------- ---------
42 01-Jan-1920 14
42 08-Jan-1920 12
42 22-Jan-1920 7
99 15-Mar-1920 18
99 22-Mar-1920 17
,其条目分布在特定数量的列中,按Stuff
展开。例如:
我需要以某种方式显示这样:
the_date
这可能吗?这些列表示自第一个id week1 week2 week3 week4 week5
-- ----- ----- ----- ----- -----
42 14 12 7
99 18 17
以来的周数,每个Entry
可能会有所不同。我不熟悉这样的数据转换 - 我应该从哪里开始?
非常感谢任何帮助。
准确地说将有194周&#34;周&#34;列。我无法重新设计数据库,这是我必须使用的。
答案 0 :(得分:1)
考虑建立一个每周数字表,其中包含从第一周到第194周开始的每个stuff_id周。您可以使用循环中传入参数的操作查询在VBA中构建它:
Public Sub WeekNumberTable()
Dim db As Database
Dim qdef As QueryDef
Dim strSQL As String
Dim i As Integer
Set db = CurrentDb
' MAKE TABLE TO INITIATE FIRST WEEK
strSQL = "SELECT stuff_ID, Min(the_date) As entry_date, 'week1' As week_number" _
& " INTO tblEntryWeekNumber" _
& " FROM tblEntry" _
& " GROUP BY stuff_ID"
db.Execute strSQL, dbFailOnError
' PREPARE SQL STRING
strSQL = "PARAMETERS DayAdd Long, WeekNumber Text(255);" _
& " INSERT INTO tblEntryWeekNumber (stuff_ID, entry_date, week_number)" _
& " SELECT stuff_ID, Min(the_date) + [DayAdd], [WeekNumber] As week_number" _
& " FROM tblEntry" _
& " GROUP BY stuff_ID"
' LOOP THROUGH ALL WEEKS ITERATIVELY FOR EACH STUFF_ID
For i = 1 To 194
Set qdef = db.CreateQueryDef("", strSQL)
qdef!DayAdd = 7 * i
qdef!WeekNumber = "week" & i
qdef.Execute , dbFailOnError
Next i
Set qdef = Nothing
Set db = Nothing
End Sub
构建此tabe后,将其连接到原始tblEntry数据并应用交叉表查询:
TRANSFORM Sum(t.the_value) AS SumOfthe_value
SELECT w.stuff_id
FROM tblEntryWeekNumber w
LEFT JOIN tblEntry t ON (w.stuff_id = t.stuff_ID)
AND (w.entry_date = t.the_date)
GROUP BY w.stuff_id
PIVOT w.week_number;
或者在 stuff_id 和 the_date / entry_date 上连接表后的Crosstab查询设计视图中:
Field: stuffId the_value weekNumber
Table: tblWeekNumber tblEntry tblWeekNumber
Total: Group By Sum Group By
Crosstab: Row Heading Value Column Heading
Sort:
Criteria:
or:
<强>输出强>
stuff_id week1 week2 week3 week4 week5 week6
42 14 12 7
99 18 17
答案 1 :(得分:0)
听起来您需要cross tab查询。
我已从Office支持网站(上面的链接)中获取这些说明。此方法使用查询向导。别担心,它并不像长指示所暗示的那么复杂!
在“创建”选项卡上的“其他”组中,单击“查询向导”。
在“新建查询”对话框中,单击“交叉表查询向导”,然后单击“确定” 单击“确定”。
“交叉表查询向导”启动。
在向导的第一页上,选择您的表或查询 想用来创建交叉表查询。
在下一页上,选择包含您的值的字段 想用作行标题。
您最多可以选择三个字段作为行标题来源,但是 您使用的行标题越少,交叉表数据表就越容易 将会阅读。
如果您选择多个字段来提供行标题,请输入 您选择的字段确定您的默认顺序 结果排序。
在下一页上,选择包含您的值的字段 想用作列标题。
通常,您应该选择包含少量值的字段 帮助您轻松阅读结果。例如,使用一个字段 只有少数可能的值(如性别)可能比较好 使用可包含许多不同值(例如年龄)的字段。
如果您选择用于列标题的字段具有 日期/时间数据类型,向导添加一个步骤,让您指定方式 将日期分组为间隔,例如月或季。
如果为列标题选择日期/时间字段,则显示下一页 向导会要求您指定用于对日期进行分组的时间间隔。 您可以指定年,季度,月,日或日期/时间。如果你这样做 不为列标题选择日期/时间字段,向导会跳过 这个页面。
在下一页上,选择要用于计算的字段和函数 汇总值。您选择的字段的数据类型确定 哪些功能可用。
在同一页面上,选中或清除是,包含行总和复选框 包括或排除行和。
如果包含行总和,则交叉表查询还有一行 标题使用与字段值相同的字段和函数。 包括行和,插入一个总结的行 剩下的专栏。例如,如果您的交叉表查询计算 按地点和性别划分的平均年龄(性别列标题), 附加列计算所有地点的平均年龄 性别。
您可以更改用于生成行总和的函数 在“设计”视图中编辑交叉表查询。
在向导的下一页上,键入查询的名称,然后 指定是要查看结果还是修改查询 设计。
您也可以使用设计器手动创建这些查询,但我建议您最初几次使用该向导。
答案 2 :(得分:0)
不需要VBA。您需要Crosstab query。
首先从您的表中创建一个基本查询,使用DatePart("ww", ...)
来计算周数,并将其连接到&#34;周&#34;。
请务必使用firstdayofweek
和firstweekofyear
的正确参数,具体取决于您所在的国家/地区。在查询中,您必须使用数字,常数在那里不可用。
如果您想要194周的列,则还需要将年添加到该字符串。
然后在该查询上运行交叉表向导。
在生成的查询中,切换到SQL视图。在那里你可以添加
PIVOT week_string IN ("week1", "week2", ...)
获取所有周数,即使几周内没有数据 见TRANSFORM statement