Выберите запись из нескольких с иерархией предпочтений в кадре данных spark или sql - PullRequest
1 голос
/ 12 марта 2020

У меня есть датафрейм товаров с одинаковым товаром разных категорий. Я хочу выбрать только одну запись на основе иерархии, например

Product ID.  Category.  Status
1.           Cat1.      status1
1.           Cat2.      status1
1.           Cat3.      status1
2.           Cat1.      status1
2.           Cat2.      status1
3.           Cat2.      status1

Если запись с Cat1 существует, выберите ее, а затем выберите Cat2. Если Cat2 не существует, выберите Cat3. Но выберите только один из нескольких.

Ответы [ 4 ]

2 голосов
/ 12 марта 2020

Используйте row_number():

select t.*
from (select t.*, row_number () over (partition by productid order by category) as seq
      from table t
     ) t
where seq = 1;

Если категории имеют разные имена, используйте case выражение

order by (case when category = 'category_x' then 1 
               when category = 'category_gg' then 2 
               else 3 
         end)
1 голос
/ 12 марта 2020

Учитывая, что ваши категории cat1., cat2., ... cat10., ...cat100.,....

Вы должны выбрать номер из категории, а затем заказать их соответственно.

SELECT * FROM
    (
        SELECT
            T.*,
            ROW_NUMBER() OVER(
                PARTITION BY PRODUCTID
                ORDER BY TO_NUMBER(REGEXP_SUBSTR(CATEGORY, '[0-9]+'))
            ) AS RN
        FROM YOUR_TABLE T
    )
WHERE RN = 1;

Приветствия !!

1 голос
/ 12 марта 2020

Здесь тот же ответ с @ Yoge sh Шарма с использованием функций фрейма данных.

import org.apache.spark.sql.expressions.Window

val w = Window.partitionBy("Product ID").orderBy("Category")
df.withColumn("row", row_number.over(w))
  .filter($"row" === 1)
  .orderBy("Product ID")
  .drop("row")
  .show

или использование groupBy и самостоятельное объединение, например

df.join(df.groupBy("Product ID").agg(first("Category").as("Category")), Seq("Product ID", "Category")).show

где те дадут вам результат:

+----------+--------+-------+
|Product ID|Category| Status|
+----------+--------+-------+
|         1|    Cat1|status1|
|         2|    Cat1|status1|
|         3|    Cat2|status1|
+----------+--------+-------+
0 голосов
/ 13 марта 2020

Я разработал приведенное ниже решение с помощью ответов Йоге sh и Ламансы

 val df1 = df.withColum("row_num", when($"category"==="Cat1", "A"),
    .when($"category" ==== "Cat2", "B"),
    .when($"category" === "Cat3", "C"))

    df1.join(df1.groupBy("product_id).agg(first("category").as("category")), 
    Seq("product_id","category")).show

При использовании в качестве заказа по категориям невозможно убедиться, что ваши предпочтения будут в желаемом порядке. Например, Cat2 может быть первым предпочтением.

Output :
+----------+--------+-------+
|Product ID|Category| Status|
+----------+--------+-------+
|         1|    Cat1|status1|
|         2|    Cat1|status1|
|         3|    Cat2|status1|
+----------+--------+-------+

Вывод:

...