from .interface import AnalyticsModuleInterface from .params import Param, ParamSchema class AttributeGroupAverage(AnalyticsModuleInterface): """Why not inherit AttributeValueCount and extend?""" description = """ """ inputs = [ ParamSchema, Param("field_name", list, required=True), Param("collection_id", required=False), Param("collection_ids", list, required=False), Param("FILTER", dict, required=False), ] outputs = [Param("group", idx=0), Param("label", idx=1), Param("value", int, idx=2)] @staticmethod def get_query( # type: ignore schema: str, collection_id: str = None, collection_ids: list = None, field_name: list = None, FILTER: dict = None, **kwargs, ) -> str: """Consider inheritng the base query""" if field_name is None or len(field_name) != 2: raise RuntimeError( "Please make sure there is exactly 2 field names " "in field_name list in chart configuration" ) with_frags = {} collection_fan = "" collection_filter = "" if collection_id is not None: collection_fan = ( f"INNER JOIN {schema}.collection_fan cf ON fa.fan_id = cf.fan_id " f"AND cf.collection_id IN (SELECT id FROM {schema}.collection WHERE id = %(collection_id)s OR parent_id = %(collection_id)s) " ) # we do the sub-query in the join part to also get children of collection if collection_ids: collection_filter += f"AND fa.collection_id IN ({', '.join(str(int(i)) for i in collection_ids)}) " for fid, field in enumerate(field_name, start=1): with_frag = f""" f{fid} as ( SELECT DISTINCT ON (fa.fan_id) fa.fan_id, fa.row_id, fa.collection_id, value FROM {schema}.fan_attribute fa {collection_fan} WHERE fa.attribute_id IN (SELECT sl.a_id FROM commons.system_label sl WHERE sl.a_system_name = '{field}') {collection_filter}) """ with_frags[f"f_{field}"] = with_frag result_query = f"""WITH {",".join(f for f in with_frags.values())} SELECT coalesce(f1.value, 'unknown') "group", avg(f2.value::float) "label", count(DISTINCT COALESCE(f1.fan_id,f2.fan_id)) "value" FROM f1 FULL OUTER JOIN f2 ON f1.fan_id = f2.fan_id GROUP BY 1 """ return result_query @staticmethod def populate_attribute_ids(conf, available_fields_list): field_names = conf["inputs"]["field_name"] if isinstance(field_names, list): attribute_ids = {} for field_name in field_names: if field_name in available_fields_list: attribute_ids[f"attr_{field_name}"] = available_fields_list.get( field_name, None ) return attribute_ids if len(attribute_ids) == 2 else None return None