Our SQL-backend family is contantly growing. Rax could already connect to SQLite, MySQL and PostgreSQL databases. Now we have also ported Rax to two major cloud databases: Microsoft Azure and AWS Redshift. The port to Azure gave us some headache due to problems with their ODBC driver for Linux. The port to Redshift was straightforward, as it’s using PostgreSQL’s syntax and ODBC driver.
Before Rax, it was difficult to compare the performance of various database systems on behavioral data, as each database vendor provides a completely different set of date and time functions, which are essential when analyzing behavioral data. With Rax, we can easily do this comparison, as Rax offers a uniform interface for time-related operations.
For testing, we use a real-life analysis: a computation of the TV reach. Below is a Rax script computing the reach of various TV channels:
// Calculate the reach per channel during a given period
{[|]}: PeriodOfInterest := {[(|)[(@)"2013-04-30",(^)"P4D"]]};
^: TvReachThreshold := (^)"PT5M";
// Map the'TvExposures' table to a Rax set
{[#:RespondentId, |:Timeslot, #:ChannelId]}:
TvExposures :=
import [
(#)"RespondentId",
(|)[(@)"StartTimeslot", (@)"EndTimeslot"],
(#)"TvChannelId"
]
"TvExposures";
// Map the 'RespondentWeights' table to a Rax set
{[#:RespondentId, #:MediaUniverseId, |:Period, &:Weight]}:
RespondentWeights :=
import [
(#)"RespondentId",
(#)"MediaUniverseId",
(|)[(@)"CAST(StartDate AS DATETIME)", (@)"CAST(EndDate AS DATETIME)"],
(&)"Weight"
]
"RespondentWeights";
// Cut the TvExposures set to the period of interest
TvExposures := TvExposures @& PeriodOfInterest;
// Add correct respondent weights to the TvExposures set
{[#:RespondentId, |:Timeslot, #:ChannelId, &:Weight]} : TvExposuresWeighted :=
project [.RespondentId#1, .Timeslot, .ChannelId, .Weight]
(TvExposures @& :[.RespondentId#1 == .RespondentId#2 && .MediaUniverseId == 100]
RespondentWeights);
// Sum the durations per respondent and channel
{[^:totalDuration, #:RespondentId, #:ChannelId, &:Weight]} : Durations :=
Gsum [.#1]:[.#2, .#3, .#4]
project [.Timeslot.absolute, .RespondentId, .ChannelId, .Weight]
TvExposuresWeighted;
// Filter very light watchers
Durations := select [.totalDuration >= TvReachThreshold] Durations;
// Compute the total size of the audience
&: TotalWeight :=
Gsum [.#1]
Gmean [.Weight]:[.RespondentId]
(RespondentWeights @& PeriodOfInterest);
// Finally, compute reach per channel
{[&:Reach, &:SampleSize, #:ChannelId]} : ReachPerChannel :=
project [.#1/TotalWeight, .#1, .#2]
Gsum [.Weight]:[.ChannelId] Durations;
// And print the results
`print ReachPerChannel;
We’ve run this script on Rax/MySQL, Rax/PostgreSQL, Rax/Azure and Rax/Redshift. The script runs on all backends essentially without changes. For Postgres-like dialects (PostgreSQL, Redshift), we had to change one of the lines in the import statement (since import contains snippets of SQL):
(|)[(@)"CAST(StartDate AS DATETIME)", (@)"CAST(EndDate AS DATETIME)"]
was changed to:
(|)[(@)"CAST(StartDate AS TIMESTAMP)", (@)"CAST(EndDate AS TIMESTAMP)"]
The data size in this experiment was rather small: the TvExposures table has approximately 400000 rows. The runtimes of the script on various database systems are plotted below (the chart was, naturally, generated by Rax). For Redshift, we tried various cluster configurations.

Somewhat surprisingly, the Azure’s SQL Server was actually slower on this query than MySQL on my local machine (Mac mini with 2.3 GHz Intel Core i7 and 8GB of memory). PostgreSQL performs rather badly. It seems to spend a lot of time on the non-equi join between TvExposures and RespondentWeights. Azure and a single-node Redshift configuration perform similarly. Increasing Redshift’s cluster size and using larger machines gave a clear performance benefit. However, the largest cluster size that we used on Redshift was 2. Scaling beyond that simply didn’t make sense for the data size in this demo.
All in all, it was an interesting experiment. However, it will be even more interesting to compare the performance of this script on real Big Data. You will read about it in one of the following blog posts. Stay put.
And for the curious, this is the query generated from this script by Rax/Azure (don’t get scared):
SELECT
*
FROM
( SELECT
A.rownum AS rownum,
(C01) / (25083.4) AS C01,
C02 AS C02
FROM
( SELECT
0 AS rownum,
SUM(C04) AS C01,
C03 AS C02
FROM
( SELECT
A.rownum AS rownum,
C01 AS C01,
C02 AS C02,
C03 AS C03,
C04 AS C04
FROM
( SELECT
0 AS rownum,
SUM(C01) AS C01,
C02 AS C02,
C03 AS C03,
C04 AS C04
FROM
( SELECT
A.rownum AS rownum,
C26 AS C01,
C01 AS C02,
C27 AS C03,
C28 AS C04
FROM
( SELECT
A.rownum AS rownum,
C01 AS C01,
C02 AS C02,
C03 AS C03,
C04 AS C04,
C05 AS C05,
C06 AS C06,
C07 AS C07,
C08 AS C08,
C09 AS C09,
C10 AS C10,
C11 AS C11,
C12 AS C12,
C13 AS C13,
C14 AS C14,
C15 AS C15,
C16 AS C16,
C17 AS C17,
C18 AS C18,
C19 AS C19,
C20 AS C20,
C21 AS C21,
C22 AS C22,
C23 AS C23,
C24 AS C24,
C25 AS C25,
C26 AS C26,
C27 AS C27,
C30 AS C28
FROM
( SELECT
0 AS rownum,
A.C01 AS C01,
CASE
WHEN (A.C02)>=(B.C03) THEN A.C02
ELSE B.C03
END AS C02,
CASE
WHEN (A.C02)>=(B.C03) THEN A.C03
ELSE B.C04
END AS C03,
CASE
WHEN (A.C02)>=(B.C03) THEN A.C04
ELSE B.C05
END AS C04,
CASE
WHEN (A.C02)>=(B.C03) THEN A.C05
ELSE B.C06
END AS C05,
CASE
WHEN (A.C02)>=(B.C03) THEN A.C06
ELSE B.C07
END AS C06,
CASE
WHEN (A.C02)>=(B.C03) THEN A.C07
ELSE B.C08
END AS C07,
CASE
WHEN (A.C02)>=(B.C03) THEN A.C08
ELSE B.C09
END AS C08,
CASE
WHEN (A.C02)>=(B.C03) THEN A.C09
ELSE B.C10
END AS C09,
CASE
WHEN (A.C02)>=(B.C03) THEN A.C10
ELSE B.C11
END AS C10,
CASE
WHEN (A.C02)>=(B.C03) THEN A.C11
ELSE B.C12
END AS C11,
CASE
WHEN (A.C02)>=(B.C03) THEN A.C12
ELSE B.C13
END AS C12,
CASE
WHEN (A.C02)>=(B.C03) THEN A.C13
ELSE B.C14
END AS C13,
CASE
WHEN (A.C14)<=(B.C15) THEN A.C14
ELSE B.C15
END AS C14,
CASE
WHEN (A.C14)<=(B.C15) THEN A.C15
ELSE B.C16
END AS C15,
CASE
WHEN (A.C14)<=(B.C15) THEN A.C16
ELSE B.C17
END AS C16,
CASE
WHEN (A.C14)<=(B.C15) THEN A.C17
ELSE B.C18
END AS C17,
CASE
WHEN (A.C14)<=(B.C15) THEN A.C18
ELSE B.C19
END AS C18,
CASE
WHEN (A.C14)<=(B.C15) THEN A.C19
ELSE B.C20
END AS C19,
CASE
WHEN (A.C14)<=(B.C15) THEN A.C20
ELSE B.C21
END AS C20,
CASE
WHEN (A.C14)<=(B.C15) THEN A.C21
ELSE B.C22
END AS C21,
CASE
WHEN (A.C14)<=(B.C15) THEN A.C22
ELSE B.C23
END AS C22,
CASE
WHEN (A.C14)<=(B.C15) THEN A.C23
ELSE B.C24
END AS C23,
CASE
WHEN (A.C14)<=(B.C15) THEN A.C24
ELSE B.C25
END AS C24,
CASE
WHEN (A.C14)<=(B.C15) THEN A.C25
ELSE B.C26
END AS C25,
CASE
WHEN (A.C14)<=(B.C15) THEN A.C14 ELSE B.C15 END - CASE WHEN (A.C02)>=(B.C03) THEN A.C02
ELSE B.C03
END AS C26,
A.C27 AS C27,
B.C01 AS C28,
B.C02 AS C29,
B.C28 AS C30
FROM
( SELECT
0 AS rownum,
A.C01 AS C01,
CASE
WHEN (A.C02)>=(B.C01) THEN A.C02
ELSE B.C01
END AS C02,
CASE
WHEN (A.C02)>=(B.C01) THEN A.C03
ELSE B.C02
END AS C03,
CASE
WHEN (A.C02)>=(B.C01) THEN A.C04
ELSE B.C03
END AS C04,
CASE
WHEN (A.C02)>=(B.C01) THEN A.C05
ELSE B.C04
END AS C05,
CASE
WHEN (A.C02)>=(B.C01) THEN A.C06
ELSE B.C05
END AS C06,
CASE
WHEN (A.C02)>=(B.C01) THEN A.C07
ELSE B.C06
END AS C07,
CASE
WHEN (A.C02)>=(B.C01) THEN A.C08
ELSE B.C07
END AS C08,
CASE
WHEN (A.C02)>=(B.C01) THEN A.C09
ELSE B.C08
END AS C09,
CASE
WHEN (A.C02)>=(B.C01) THEN A.C10
ELSE B.C09
END AS C10,
CASE
WHEN (A.C02)>=(B.C01) THEN A.C11
ELSE B.C10
END AS C11,
CASE
WHEN (A.C02)>=(B.C01) THEN A.C12
ELSE B.C11
END AS C12,
CASE
WHEN (A.C02)>=(B.C01) THEN A.C13
ELSE B.C12
END AS C13,
CASE
WHEN (A.C14)<=(B.C13) THEN A.C14
ELSE B.C13
END AS C14,
CASE
WHEN (A.C14)<=(B.C13) THEN A.C15
ELSE B.C14
END AS C15,
CASE
WHEN (A.C14)<=(B.C13) THEN A.C16
ELSE B.C15
END AS C16,
CASE
WHEN (A.C14)<=(B.C13) THEN A.C17
ELSE B.C16
END AS C17,
CASE
WHEN (A.C14)<=(B.C13) THEN A.C18
ELSE B.C17
END AS C18,
CASE
WHEN (A.C14)<=(B.C13) THEN A.C19
ELSE B.C18
END AS C19,
CASE
WHEN (A.C14)<=(B.C13) THEN A.C20
ELSE B.C19
END AS C20,
CASE
WHEN (A.C14)<=(B.C13) THEN A.C21
ELSE B.C20
END AS C21,
CASE
WHEN (A.C14)<=(B.C13) THEN A.C22
ELSE B.C21
END AS C22,
CASE
WHEN (A.C14)<=(B.C13) THEN A.C23
ELSE B.C22
END AS C23,
CASE
WHEN (A.C14)<=(B.C13) THEN A.C24
ELSE B.C23
END AS C24,
CASE
WHEN (A.C14)<=(B.C13) THEN A.C25
ELSE B.C24
END AS C25,
CASE
WHEN (A.C14)<=(B.C13) THEN A.C14 ELSE B.C13 END - CASE WHEN (A.C02)>=(B.C01) THEN A.C02
ELSE B.C01
END AS C26,
A.C27 AS C27
FROM
( SELECT
0 AS rownum,
RespondentId AS C01,
((DATEPART(DAY,
StartTimeslot))+FLOOR((153*((DATEPART(MONTH,
StartTimeslot))+12*FLOOR(((14-(DATEPART(MONTH,
StartTimeslot)))/12))-3)+2)/5)+365*((DATEPART(YEAR,
StartTimeslot))+4800-FLOOR(((14-(DATEPART(MONTH,
StartTimeslot)))/12)))+FLOOR(((DATEPART(YEAR,
StartTimeslot))+4800-FLOOR(((14-(DATEPART(MONTH,
StartTimeslot)))/12)))/4)-FLOOR(((DATEPART(YEAR,
StartTimeslot))+4800-FLOOR(((14-(DATEPART(MONTH,
StartTimeslot)))/12)))/100)+FLOOR(((DATEPART(YEAR,
StartTimeslot))+4800-FLOOR(((14-(DATEPART(MONTH,
StartTimeslot)))/12)))/400)-32045)*CAST(864000000 AS BIGINT)+(((DATEPART(HOUR,
StartTimeslot))-12)*CAST(864000000 AS BIGINT))/24+((DATEPART(MINUTE,
StartTimeslot))*CAST(864000000 AS BIGINT))/(24*60)+((DATEPART(SECOND,
StartTimeslot))*CAST(864000000 AS BIGINT)+((DATEPART(MICROSECOND,
StartTimeslot))/100)/10000)/(24*60*60) AS C02,
0 AS C03,
0 AS C04,
0 AS C05,
0 AS C06,
0 AS C07,
0 AS C08,
0 AS C09,
0 AS C10,
0 AS C11,
0 AS C12,
0 AS C13,
((DATEPART(DAY,
EndTimeslot))+FLOOR((153*((DATEPART(MONTH,
EndTimeslot))+12*FLOOR(((14-(DATEPART(MONTH,
EndTimeslot)))/12))-3)+2)/5)+365*((DATEPART(YEAR,
EndTimeslot))+4800-FLOOR(((14-(DATEPART(MONTH,
EndTimeslot)))/12)))+FLOOR(((DATEPART(YEAR,
EndTimeslot))+4800-FLOOR(((14-(DATEPART(MONTH,
EndTimeslot)))/12)))/4)-FLOOR(((DATEPART(YEAR,
EndTimeslot))+4800-FLOOR(((14-(DATEPART(MONTH,
EndTimeslot)))/12)))/100)+FLOOR(((DATEPART(YEAR,
EndTimeslot))+4800-FLOOR(((14-(DATEPART(MONTH,
EndTimeslot)))/12)))/400)-32045)*CAST(864000000 AS BIGINT)+(((DATEPART(HOUR,
EndTimeslot))-12)*CAST(864000000 AS BIGINT))/24+((DATEPART(MINUTE,
EndTimeslot))*CAST(864000000 AS BIGINT))/(24*60)+((DATEPART(SECOND,
EndTimeslot))*CAST(864000000 AS BIGINT)+((DATEPART(MICROSECOND,
EndTimeslot))/100)/10000)/(24*60*60) AS C14,
0 AS C15,
0 AS C16,
0 AS C17,
0 AS C18,
0 AS C19,
0 AS C20,
0 AS C21,
0 AS C22,
0 AS C23,
0 AS C24,
0 AS C25,
(((DATEPART(DAY,
EndTimeslot))+FLOOR((153*((DATEPART(MONTH,
EndTimeslot))+12*FLOOR(((14-(DATEPART(MONTH,
EndTimeslot)))/12))-3)+2)/5)+365*((DATEPART(YEAR,
EndTimeslot))+4800-FLOOR(((14-(DATEPART(MONTH,
EndTimeslot)))/12)))+FLOOR(((DATEPART(YEAR,
EndTimeslot))+4800-FLOOR(((14-(DATEPART(MONTH,
EndTimeslot)))/12)))/4)-FLOOR(((DATEPART(YEAR,
EndTimeslot))+4800-FLOOR(((14-(DATEPART(MONTH,
EndTimeslot)))/12)))/100)+FLOOR(((DATEPART(YEAR,
EndTimeslot))+4800-FLOOR(((14-(DATEPART(MONTH,
EndTimeslot)))/12)))/400)-32045)*CAST(864000000 AS BIGINT)+(((DATEPART(HOUR,
EndTimeslot))-12)*CAST(864000000 AS BIGINT))/24+((DATEPART(MINUTE,
EndTimeslot))*CAST(864000000 AS BIGINT))/(24*60)+((DATEPART(SECOND,
EndTimeslot))*CAST(864000000 AS BIGINT)+((DATEPART(MICROSECOND,
EndTimeslot))/100)/10000)/(24*60*60))-(((DATEPART(DAY,
StartTimeslot))+FLOOR((153*((DATEPART(MONTH,
StartTimeslot))+12*FLOOR(((14-(DATEPART(MONTH,
StartTimeslot)))/12))-3)+2)/5)+365*((DATEPART(YEAR,
StartTimeslot))+4800-FLOOR(((14-(DATEPART(MONTH,
StartTimeslot)))/12)))+FLOOR(((DATEPART(YEAR,
StartTimeslot))+4800-FLOOR(((14-(DATEPART(MONTH,
StartTimeslot)))/12)))/4)-FLOOR(((DATEPART(YEAR,
StartTimeslot))+4800-FLOOR(((14-(DATEPART(MONTH,
StartTimeslot)))/12)))/100)+FLOOR(((DATEPART(YEAR,
StartTimeslot))+4800-FLOOR(((14-(DATEPART(MONTH,
StartTimeslot)))/12)))/400)-32045)*CAST(864000000 AS BIGINT)+(((DATEPART(HOUR,
StartTimeslot))-12)*CAST(864000000 AS BIGINT))/24+((DATEPART(MINUTE,
StartTimeslot))*CAST(864000000 AS BIGINT))/(24*60)+((DATEPART(SECOND,
StartTimeslot))*CAST(864000000 AS BIGINT)+((DATEPART(MICROSECOND,
StartTimeslot))/100)/10000)/(24*60*60)) AS C26 ,
TvChannelId AS C27
FROM
TvExposures) AS A
INNER JOIN
(
SELECT
1 AS rownum,
2122339536000000 AS C01,
2013 AS C02,
3 AS C03,
28 AS C04,
0 AS C05,
0 AS C06,
0 AS C07,
0 AS C08,
18 AS C09,
0 AS C10,
2013 AS C11,
118 AS C12,
2122365456000000 AS C13,
2013 AS C14,
4 AS C15,
28 AS C16,
0 AS C17,
0 AS C18,
0 AS C19,
0 AS C20,
22 AS C21,
2 AS C22,
2013 AS C23,
148 AS C24,
25920000000 AS C25
) AS B
ON A.C14 > B.C01
AND A.C02 < B.C13 ) AS A INNER JOIN ( SELECT 0 AS rownum, RespondentId AS C01, MediaUniverseId AS C02, ((DATEPART(DAY, CAST(StartDate AS DATETIME)))+FLOOR((153*((DATEPART(MONTH, CAST(StartDate AS DATETIME)))+12*FLOOR(((14-(DATEPART(MONTH, CAST(StartDate AS DATETIME))))/12))-3)+2)/5)+365*((DATEPART(YEAR, CAST(StartDate AS DATETIME)))+4800-FLOOR(((14-(DATEPART(MONTH, CAST(StartDate AS DATETIME))))/12)))+FLOOR(((DATEPART(YEAR, CAST(StartDate AS DATETIME)))+4800-FLOOR(((14-(DATEPART(MONTH, CAST(StartDate AS DATETIME))))/12)))/4)-FLOOR(((DATEPART(YEAR, CAST(StartDate AS DATETIME)))+4800-FLOOR(((14-(DATEPART(MONTH, CAST(StartDate AS DATETIME))))/12)))/100)+FLOOR(((DATEPART(YEAR, CAST(StartDate AS DATETIME)))+4800-FLOOR(((14-(DATEPART(MONTH, CAST(StartDate AS DATETIME))))/12)))/400)-32045)*CAST(864000000 AS BIGINT)+(((DATEPART(HOUR, CAST(StartDate AS DATETIME)))-12)*CAST(864000000 AS BIGINT))/24+((DATEPART(MINUTE, CAST(StartDate AS DATETIME)))*CAST(864000000 AS BIGINT))/(24*60)+((DATEPART(SECOND, CAST(StartDate AS DATETIME)))*CAST(864000000 AS BIGINT)+((DATEPART(MICROSECOND, CAST(StartDate AS DATETIME)))/100)/10000)/(24*60*60) AS C03, 0 AS C04, 0 AS C05, 0 AS C06, 0 AS C07, 0 AS C08, 0 AS C09, 0 AS C10, 0 AS C11, 0 AS C12, 0 AS C13, 0 AS C14, ((DATEPART(DAY, CAST(EndDate AS DATETIME)))+FLOOR((153*((DATEPART(MONTH, CAST(EndDate AS DATETIME)))+12*FLOOR(((14-(DATEPART(MONTH, CAST(EndDate AS DATETIME))))/12))-3)+2)/5)+365*((DATEPART(YEAR, CAST(EndDate AS DATETIME)))+4800-FLOOR(((14-(DATEPART(MONTH, CAST(EndDate AS DATETIME))))/12)))+FLOOR(((DATEPART(YEAR, CAST(EndDate AS DATETIME)))+4800-FLOOR(((14-(DATEPART(MONTH, CAST(EndDate AS DATETIME))))/12)))/4)-FLOOR(((DATEPART(YEAR, CAST(EndDate AS DATETIME)))+4800-FLOOR(((14-(DATEPART(MONTH, CAST(EndDate AS DATETIME))))/12)))/100)+FLOOR(((DATEPART(YEAR, CAST(EndDate AS DATETIME)))+4800-FLOOR(((14-(DATEPART(MONTH, CAST(EndDate AS DATETIME))))/12)))/400)-32045)*CAST(864000000 AS BIGINT)+(((DATEPART(HOUR, CAST(EndDate AS DATETIME)))-12)*CAST(864000000 AS BIGINT))/24+((DATEPART(MINUTE, CAST(EndDate AS DATETIME)))*CAST(864000000 AS BIGINT))/(24*60)+((DATEPART(SECOND, CAST(EndDate AS DATETIME)))*CAST(864000000 AS BIGINT)+((DATEPART(MICROSECOND, CAST(EndDate AS DATETIME)))/100)/10000)/(24*60*60) AS C15, 0 AS C16, 0 AS C17, 0 AS C18, 0 AS C19, 0 AS C20, 0 AS C21, 0 AS C22, 0 AS C23, 0 AS C24, 0 AS C25, 0 AS C26, (((DATEPART(DAY, CAST(EndDate AS DATETIME)))+FLOOR((153*((DATEPART(MONTH, CAST(EndDate AS DATETIME)))+12*FLOOR(((14-(DATEPART(MONTH, CAST(EndDate AS DATETIME))))/12))-3)+2)/5)+365*((DATEPART(YEAR, CAST(EndDate AS DATETIME)))+4800-FLOOR(((14-(DATEPART(MONTH, CAST(EndDate AS DATETIME))))/12)))+FLOOR(((DATEPART(YEAR, CAST(EndDate AS DATETIME)))+4800-FLOOR(((14-(DATEPART(MONTH, CAST(EndDate AS DATETIME))))/12)))/4)-FLOOR(((DATEPART(YEAR, CAST(EndDate AS DATETIME)))+4800-FLOOR(((14-(DATEPART(MONTH, CAST(EndDate AS DATETIME))))/12)))/100)+FLOOR(((DATEPART(YEAR, CAST(EndDate AS DATETIME)))+4800-FLOOR(((14-(DATEPART(MONTH, CAST(EndDate AS DATETIME))))/12)))/400)-32045)*CAST(864000000 AS BIGINT)+(((DATEPART(HOUR, CAST(EndDate AS DATETIME)))-12)*CAST(864000000 AS BIGINT))/24+((DATEPART(MINUTE, CAST(EndDate AS DATETIME)))*CAST(864000000 AS BIGINT))/(24*60)+((DATEPART(SECOND, CAST(EndDate AS DATETIME)))*CAST(864000000 AS BIGINT)+((DATEPART(MICROSECOND, CAST(EndDate AS DATETIME)))/100)/10000)/(24*60*60))-(((DATEPART(DAY, CAST(StartDate AS DATETIME)))+FLOOR((153*((DATEPART(MONTH, CAST(StartDate AS DATETIME)))+12*FLOOR(((14-(DATEPART(MONTH, CAST(StartDate AS DATETIME))))/12))-3)+2)/5)+365*((DATEPART(YEAR, CAST(StartDate AS DATETIME)))+4800-FLOOR(((14-(DATEPART(MONTH, CAST(StartDate AS DATETIME))))/12)))+FLOOR(((DATEPART(YEAR, CAST(StartDate AS DATETIME)))+4800-FLOOR(((14-(DATEPART(MONTH, CAST(StartDate AS DATETIME))))/12)))/4)-FLOOR(((DATEPART(YEAR, CAST(StartDate AS DATETIME)))+4800-FLOOR(((14-(DATEPART(MONTH, CAST(StartDate AS DATETIME))))/12)))/100)+FLOOR(((DATEPART(YEAR, CAST(StartDate AS DATETIME)))+4800-FLOOR(((14-(DATEPART(MONTH, CAST(StartDate AS DATETIME))))/12)))/400)-32045)*CAST(864000000 AS BIGINT)+(((DATEPART(HOUR, CAST(StartDate AS DATETIME)))-12)*CAST(864000000 AS BIGINT))/24+((DATEPART(MINUTE, CAST(StartDate AS DATETIME)))*CAST(864000000 AS BIGINT))/(24*60)+((DATEPART(SECOND, CAST(StartDate AS DATETIME)))*CAST(864000000 AS BIGINT)+((DATEPART(MICROSECOND, CAST(StartDate AS DATETIME)))/100)/10000)/(24*60*60)) AS C27 , Weight AS C28 FROM RespondentWeights ) AS B ON A.C14 > B.C03
AND A.C02 < B.C15 AND A.C01 = B.C01 AND B.C02 = 100 ) AS A ) AS A ) AS A GROUP BY C02, C03, C04) AS A WHERE (C01) >= (3000000)
) AS A
GROUP BY
C03) AS A ) AS T
