我的数据结构如下:
ID | Enrolment_Date | Appointment1_Date | Appointment2_Date | .... | Appointment150_Date |
112 01/01/2015 01/02/2015 01/03/2018 01/08/2018
113 01/06/2018 01/07/2018 NULL NULL
114 01/04/2018 01/05/2018 01/06/2018 NULL
我需要一个新的变量,用于计算enrollment_date和最近的约会之间的月数。面临的挑战是所有个人都有不同数量的约会。
更新:我同意以下意见:表设计不佳,需要重新格式化。提议的解决方案可以包括关于如何转换表格的建议代码吗?
答案 0 :(得分:0)
您将需要重组数据,因为给定的结构数据库设计不佳。
创建两个单独的表-一个称为用户,另一个称为约会。 users表包含用户ID,注册日期和任何其他特定的用户信息。约会表中的每一行都包含用户的唯一ID和特定的约会日期。这样构造表将使编写查询以使自上次约会以来的天数/月数变得更容易。
例如:
Users Table:
ID, Enrollment_Date
1, 2018-01-01
2, 2018-03-02
3, 2018-05-02
Appointments Table:
ID, Appointment_Date
1, 2018-01-02
1, 2018-02-02
1, 2018-02-10
2, 2018-05-01
然后,您将可以编写查询以将两个表连接在一起,并计算注册日期和约会日期的最小值之间的差。
答案 1 :(得分:0)
最好创建两个表。
注册表(dbo.Enrollments)
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if info.count > 0 {
collectionView.scrollToItem(at: IndexPath(item:info.count - 1, section: 0), at: .top, animated: false)
}
}
约会表(dbo。约会)
ID | EnrolmentDate
1 | 2018-08-30
2 | 2018-08-31
然后您可以尝试这样的事情。
如果您希望从注册日期到最终任命日期的月份数,请使用以下查询。
ID | EnrolmentID | AppointmentDate
1 | 1 | 2018-09-02
2 | 1 | 2018-09-03
3 | 2 | 2018-09-01
4 | 2 | 2018-09-03
并且,如果您希望从注册日期到最接近的约会日期的月份数,请使用以下查询。
SELECT E.ID, E.EnrolmentDate, A.NoOfMonths
FROM dbo.Enrolments E
OUTER APPLY
(
SELECT DATEDIFF(mm, E.EnrolmentDate, MAX(A.AppointmentDate)) AS NoOfMonths
FROM dbo.Appointments A
WHERE A.EnrolmentId = E.ID
) A
在sqlfiddle上尝试
答案 2 :(得分:0)
由于OP当前停留在这种不良设计中,因此我将提出一个临时解决方案。正如其他人所建议的,您实际上必须在这里更改结构。目前,这已足够:
SELECT '['+ NAME + '],' FROM sys.columns WHERE OBJECT_ID = OBJECT_ID ('TableA') -- find all columns, last one probably max appointment date
SELECT ID,
Enrolment_Date,
CASE WHEN Appointment150_Date IS NOT NULL THEN DATEDIFF (MONTH, Enrolment_Date, Appointment150_Date)
WHEN Appointment149_Date IS NOT NULL THEN DATEDIFF (MONTH, Enrolment_Date, Appointment149_Date)
WHEN Appointment148_Date IS NOT NULL THEN DATEDIFF (MONTH, Enrolment_Date, Appointment148_Date)
WHEN Appointment147_Date IS NOT NULL THEN DATEDIFF (MONTH, Enrolment_Date, Appointment147_Date)
WHEN Appointment146_Date IS NOT NULL THEN DATEDIFF (MONTH, Enrolment_Date, Appointment146_Date)
WHEN Appointment145_Date IS NOT NULL THEN DATEDIFF (MONTH, Enrolment_Date, Appointment145_Date)
WHEN Appointment144_Date IS NOT NULL THEN DATEDIFF (MONTH, Enrolment_Date, Appointment144_Date) -- and so on
END AS NumberOfMonths
FROM TableA
这是一个非常丑陋的临时解决方案,应该这样考虑。
答案 3 :(得分:0)
您有一个糟糕的数据结构,正如其他人指出的那样。您实际上是一张桌子,每个约会一行。毕竟,第150次约会后会发生什么?
select t.id, t.Enrolment_Date,
datediff(month, t.Enrolment_Date, m.max_Appointment_Date) as months_diff
from t cross apply
(select max(Appointment_Date) as max_Appointment_Date
from (values (Appointment1_Date),
(Appointment2_Date),
. . .
(Appointment150_Date)
) v(Appointment_Date)
) m;