Error Pyspark mientras se ejecuta subquery sql "AnalysisExcepción: u"La columna relacionada no se permite en un predicado de calidad:\nAggregate"
Había escrito una consulta SQL que tiene una subquería en ella. Es una consulta mySQL correcta pero no se implementa en Pyspark
from pyspark import SparkContext, SparkConf
from pyspark.sql import SparkSession
from pyspark.sql import HiveContext
from pyspark.sql.types import *
from pyspark.sql.window import Window
from pyspark.sql.functions import *
sc = spark.sparkContext
sqlcontext = HiveContext(sc)
select location, postal, max(spend), max(revenue)
from (select a.*,
(select sum(r.revenue)
from revenue r
where r.user = a.user and
r.dte >= a.dt - interval 10 minute and
r.dte <= a.dte + interval 10 minute
) as revenue
from auction a
where a.event in ('Mid', 'End', 'Show') and
a.cat_id in (3) and
a.cat = 'B'
) a
group by location, postal;
El error que estoy recibiendo es
AnalysisException: u"Correlated column is not allowed in a non-equality predicate:\nAggregate [sum(cast(revenue#17 as double)) AS sum(CAST(revenue AS DOUBLE))#498]\n+- Filter (((user#2 = outer(user#85)) && (dt#0 >= cast(cast(outer(dt#67) - interval 10 minutes as timestamp) as string))) && ((dt#0 <= cast(cast(outer(dt#67) + interval 10 minutes as timestamp) as string))
Cualquier información sobre esto será útil.
Pregunta hecha hace 3 años, 4 meses, 28 días - Por debugdynamob312
3 Respuestas:
-
Correlated subquery using sql syntax in PySpark is not an option, so in this case I ran the consultas seperately with some twigs in sql query and left joined it using
df.join
para obtener la salida deseada a través de PySpark, así es como se resolvió este problemaRespondida el Dec 18, 2020 a las 14:26 - por markupmaestro
Votos positivos: 0 | Votos negativos: 0 -
El error que estás viendo se refiere a la incompatibilidad de la sintaxis SQL utilizada en la subquery dentro de la cláusula
SELECT
en Pyspark. En Pyspark, no es posible hacer referencia a columnas en una subconsulta de la misma manera que en SQL estándar.Para solucionar este problema y que la consulta sea ejecutada en Pyspark, puedes reformular tu consulta SQL para eliminar la subquery y utilizar operaciones de tipo join o window functions para lograr el mismo resultado. Aquí tienes un ejemplo de cómo podrías reformular tu consulta:
python
Primero, cargamos los datos de las tablas auction y revenue
auction_df = sqlcontext.table("auction") revenue_df = sqlcontext.table("revenue")Realizamos las operaciones de filtrado y cálculo de revenue
filtered_auction_df = auction_df.filter((col("event").isin('Mid', 'End', 'Show')) & (col("cat_id") == 3) & (col("cat") == 'B')) revenue_df = revenue_df.withColumn("revenue_interval", col("dte").between(col("dt") - expr("INTERVAL 10 MINUTES"), col("dt") + expr("INTERVAL 10 MINUTES")))Realizamos un join entre las dos tablas para obtener el resultado deseado
result_df = filtered_auction_df.join(revenue_df, filtered_auction_df["user"] == revenue_df["user"] & revenue_df["revenue_interval"], "left")Realizamos la agregación y el group by
final_result = result_df.groupBy("location", "postal").agg(max("spend").alias("max_spend"), max("revenue").alias("max_revenue"))Mostramos el resultado final
final_result.show()En resumen, en lugar de la subquery, utilizamos operaciones de filtro, join y agregación para lograr el mismo resultado de la consulta original en Pyspark. Espero que esta solución te sea de ayuda. Si tienes alguna otra pregunta o duda, no dudes en decirme.
Respondida el Dec 19, 2020 a las 14:21 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
El error que estás recibiendo se debe a que estás intentando utilizar una columna relacionada en un predicado no de igualdad dentro de una subconsulta correlacionada. Esto no está permitido en Apache Spark.
En tu consulta, estás utilizando la columna
user
de la tabla externarevenue
en un predicado de igualdad dentro de la subconsulta correlacionada. Esto no está permitido porque la columnauser
está relacionada con la tabla externa y, por lo tanto, no se puede utilizar en un predicado no de igualdad.Para resolver este problema, puedes utilizar una unión en lugar de una subconsulta correlacionada. Aquí tienes una consulta modificada que utiliza una unión:
select location, postal, max(spend), max(revenue) from ( select a.*, r.revenue from auction a left join revenue r on a.user = r.user and r.dte >= a.dt - interval 10 minute and r.dte <= a.dt + interval 10 minute where a.event in ('Mid', 'End', 'Show') and a.cat_id in (3) and a.cat = 'B' ) a group by location, postal;
Esta consulta utiliza una unión para unir las tablas
auction
yrevenue
en función de la columnauser
. Esto te permite acceder a la columnarevenue
de la tablarevenue
sin utilizar una subconsulta correlacionada.Respondida el Dec 19, 2020 a las 14:35 - por Gemini
Votos positivos: 0 | Votos negativos: 0