Удалить оба дубликата строки - PullRequest
0 голосов

Добрый день, коллеги. У меня большой набор данных (около 237 000 000 строк). Есть много столбцов. Например, мне нужно удалить все дубликаты с именами столбцов userId, VTS.

userId Vts moreColumn1 moreColumn2
10     150     2           3              -delete
11     160     1           6
10     150     0           1              -delete

Я плохо с SQL. Попробовал другой вариант из интернета, но он не работает.

UPDATE:

Ты за ответы! Я забыл сказать, что я использую Java. Вот мой оптимизированный код для Java:

viewingDataset.groupBy("userId", "VTS")
                .count()
                .where("count = 1")
                .drop("count")
                .join(viewingDataset, JavaConversions.asScalaBuffer(asList("userId", "VTS")))

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Вы можете достичь желаемого с помощью оконных функций:

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

ds.withColumn("aux", count("*")
.over(Window.partitionBy($"userId", $"VTS")))
.where($"aux"===1)
.drop($"aux")

partitionBy будет подсчитывать, сколько элементов по разделам, в соответствии со столбцами, которые вы отправляете в качестве параметров (userId и VTS в вашем примере). Затем с помощью предложения where мы будем хранить только строки из разделов, в которых количество равно 1, то есть уникальные строки.

Результат предложения partitionBY

ds.withColumn("aux", count("*").over(Window.partitionBy($"userId", $"VTS"))).show

+-------+----+------------+------------+---+
| userId| VTS| moreColumn1| moreColumn2|aux|
+-------+----+------------+------------+---+
|     10| 150|           2|           3|  2|
|     10| 150|           0|           1|  2|
|     11| 160|           1|           6|  1|
+-------+----+------------+------------+---+

Окончательный результат

+-------+----+------------+------------+
| userId| VTS| moreColumn1| moreColumn2|
+-------+----+------------+------------+
|     11| 160|           1|           6|
+-------+----+------------+------------+
0 голосов
/ 04 июля 2018

Вы можете объединиться с количеством, отфильтровать результат и присоединиться обратно

df.groupBy("userId", "Vts").count
  .where($"count" === 1)
  .drop("count")
  .join(df, Seq("userId", "Vts"))

Можно получить тот же результат с оконными функциями, но он менее надежен, если данные искажены, и в среднем намного дороже.

...