def get_query(self):
        """Returns SQL query that will be used to create the M-formatted table
        """
        start_time = self.__start_time
        stop_time = self.__stop_time
        if self.__convert_to_unix_time:
            start_time = utils.to_unix_time(start_time)
            stop_time = utils.to_unix_time(stop_time)
        try:
            # If times are numbers, their string representations don't have
            # surrounding single quotes. Otherwise, they do
            float(start_time)
        except ValueError:
            start_time = "'{}'".format(start_time)
        try:
            float(stop_time)
        except ValueError:
            stop_time = "'{}'".format(start_time)

        col_specs = self.__col_specs
        conn = self.__conn
        table_name = self.__rg_table_name

        # get all features
        sql_features = "SELECT DISTINCT {} FROM {};".format(col_specs["feature"], table_name)
        feat_names = [row[0] for row in conn.execute(sql_features)]

        # figure out aggregations
        aggregations = {
            feat_name: self.__aggregations[feat_name]
            if self.__aggregations.has_key(feat_name)
            else self.__default_aggregation
            for feat_name in feat_names
        }

        # Now we build the complicated sql query
        sql_select_clause = "SELECT id_tbl.id, {} ".format(
            ", ".join(["{0}_tbl.val AS {0}".format(feat) for feat in feat_names])
        )
        sql_from_clause_top = ("FROM ({}SELECT DISTINCT {} AS id FROM {}) id_tbl " "LEFT JOIN ").format(
            "(" * len(feat_names), col_specs["unit_id"], table_name
        )
        sql_from_clause_features = "LEFT JOIN ".join(
            [
                (
                    "(SELECT {unit_id_col} AS id, {aggr}({val_col}) AS val FROM "
                    "{table_name} WHERE "
                    "{feature_col} = '{feat_name}' AND "
                    "(({start_time_col} >= {start_time} "
                    "  AND {start_time_col} <= {stop_time}) "
                    " OR {start_time_col} IS NULL) AND "
                    "(({stop_time_col} >= {start_time} "
                    "  AND {stop_time_col} <= {stop_time}) "
                    " OR {stop_time_col} IS NULL) "
                    "GROUP BY id) {feat_name}_tbl ON "
                    "id_tbl.id = {feat_name}_tbl.id) "
                ).format(
                    unit_id_col=col_specs["unit_id"],
                    aggr=aggregations[feat_name],
                    val_col=col_specs["val"],
                    table_name=table_name,
                    feature_col=col_specs["feature"],
                    start_time_col=col_specs["start_time"],
                    start_time=start_time,
                    stop_time_col=col_specs["stop_time"],
                    stop_time=stop_time,
                    feat_name=feat_name,
                )
                for feat_name in feat_names
            ]
        )
        # TODO we can probably do something more sophisticated than just
        # throwing the user's directives in here
        sql_where_clause = ""
        if self.__selections:
            sql_where_clause = "WHERE " + "AND ".join(["({})".format(sel) for sel in self.__selections])
        sql_select = "{} {} {} {}".format(
            sql_select_clause, sql_from_clause_top, sql_from_clause_features, sql_where_clause
        )
        return sql_select