快速背景,以便我的问题有意义:系统以问卷形式从用户收集数据。用户属于组织,组织属于部门,问题/计算(如调查问卷中所示)在各部门之间有所不同。 (问题由用户回答;计算由系统计算)。
存在以下表格:
部门(SectorID,名称)
组织(OrganisationID,Name,SectorID)
年(年份ID,姓名)
问题(QuestionID,DisplayText,CommonName,SectorID)
答案(AnswerID,答案,OrganisationID,YearID,QuestionID)
计算(CalculationID,DisplayText,CommonName,SectorID)
CalculationResults (CalculationResultID,Result,OrganisationID,YearID,CalculationID)
我需要以下列方式显示数据:
使这个特别复杂的事情(对我而言)是问题在他们所属的不同部门以不同方式显示(对用户),但其中一些问题仍然是常见问题。例如。 "制造销售"与#34;销售(制造)"相同。我需要使用CommonName
字段来确定共性。
我设法使用SQL Pivot接近我想要的东西 - SQL Fiddle(如果你运行SQL,你会注意到空值和"共性"问题)。但是我的尝试中缺少一些东西:
通用名和列名 - 我需要将列名称设为CommonName
字段,而不是QuestionID
字段。
我只选择了答案表 - 我还需要从结构相同的 CalculationResults 表中进行选择。
编辑:SQL小提琴数据所需的结果是:
(具有橙色角的两个块需要一直向左移动,因此问题总共有3列 - 3个唯一CommonName
值。接下来的3列是3个唯一的计算的CommonName
值。如果不让我知道,我希望我有道理。)
Edit2 :另一个编辑只是为了好玩。我一直在考虑重新设计数据库,但在现阶段它不是一个选项 - 在这个遗留系统上风险太大。如果有人看到设计并认为。我希望以Pivot的形式提供解决方案。
答案 0 :(得分:1)
基本上我们希望获得print new
mmsi d ts lat lon
0 0 77 1458213600 46.367553 48.01107
1 0 77 1458214200 46.367553 48.01107
2 0 77 1458213000 46.367553 48.01107
3 0 77 1458215400 46.367553 48.01107
4 0 77 1458217200 46.367553 48.01107
print old
mmsi d lat lon ts
0 0 77 48.01107 122.179 1458213600
1 0 77 48.01107 122.179 1458214200
2 0 77 48.01107 122.179 1458214800
3 0 77 48.01107 122.179 1458217200
4 0 77 48.01107 122.179 1458220800
#added custom suffixes
print pd.merge(new,old,on=['mmsi','d','ts'], how='inner', suffixes=('_new','_old'))
mmsi d ts lat_new lon_new lat_old lon_old
0 0 77 1458213600 46.367553 48.01107 48.01107 122.179
1 0 77 1458214200 46.367553 48.01107 48.01107 122.179
2 0 77 1458217200 46.367553 48.01107 48.01107 122.179
QuestionID
Grouped By
和SectorID
的顺序。
您可以使用Name
执行此操作,如下所示:
PARTITION BY
这应该这样做:
ROW_NUMBER() OVER(PARTITION BY q.SectorID, y.Name ORDER BY a.QuestionID)
结果:
答案 1 :(得分:1)
有时候您可以使用PIVOT
代替[Aggregate](CASE EXPRESSION)
来获取相同的数据。有时候它会更快。
对于您的问题,您可以将OUTER APPLY
与动态MAX(CASE)
DECLARE @Questions NVARCHAR(MAX),
@Calculations NVARCHAR(MAX),
@Sql NVARCHAR(MAX)
SELECT @Questions = COALESCE(@Questions + ', ', '')
+ 'MAX(CASE WHEN q.CommonName = ''' + CommonName + ''' THEN a.Answer END) AS ' + QUOTENAME(CommonName)
FROM Questions
GROUP BY CommonName
SELECT @Calculations = COALESCE(@Calculations + ', ', '')
+ 'MAX(CASE WHEN c.CommonName = ''' + CommonName + ''' THEN cr.Result END) AS ' + QUOTENAME(CommonName)
FROM Calculations
GROUP BY CommonName
SET @Sql = N'
SELECT
o.Name As [Organisation],
y.Name As [Year],
q.*,
c.*
FROM
Organisations o
CROSS JOIN Years y
OUTER APPLY (
SELECT ' + @Questions + '
FROM Answers a
JOIN Questions q ON a.QuestionID = q.QuestionID
WHERE a.OrganisationID = o.OrganisationID
AND a.YearID = y.YearID
) q
OUTER APPLY (
SELECT ' + @Calculations + '
FROM CalculationResults cr
JOIN Calculations c ON cr.CalculationID = c.CalculationID
WHERE cr.OrganisationID = o.OrganisationID
AND cr.YearID = y.YearID
) c
'