Проблема с вашим приложением foldLeft
заключается в том, что оно не эквивалентно выражению, которое вы хотите использовать.
Как вы уже сказали, вы ищете
sha2(b, 256) = b_hash OR sha2(c, 256) = c_hash OR sha2(d, 256) = d_hash
, в то время как цепочечный фильтр на DataFrame
приводит к
sha2(b, 256) = b_hash AND sha2(c, 256) = c_hash AND sha2(d, 256) = d_hash
Чтобы достичь первого, вы должны изменить аккумулятор:
import org.apache.spark.sql.functions.{col, lit}
import org.apache.spark.sql.Column
val atLeastOneMatch: Column = map.foldLeft(lit(false)) {
case (acc, (c, h)) => acc or (sha2(col(c), 256) === h)
}
и затем использовать результат для фильтрации данных
df.filter(atLeastOneMatch).count
Это будет считать все строки , где хотя бы один столбец соответствует хешу предоставлено в map
. По законам Де Моргана его отрицание
!atLeastOneMatch
будет эквивалентно
sha2(b, 256) != b_hash AND sha2(c, 256) != c_hash AND sha2(d, 256) = d_hash
Другими словами, оно будет соответствовать случаям, когда ни одно из значений не соответствует соответствующему хешу. [+1139]
Если вы хотите найти строки, в которых хотя бы одно значение не соответствует хешу , вам следует использовать
sha2(b, 256) != b_hash OR sha2(c, 256) != c_hash OR sha2(d, 256) != d_hash
, который можно составить, как показано ниже
[ 117]
Это отрицание
!atLeastOneMismatch
эквивалентно (законы де Моргана еще раз)
sha2(b, 256) = b_hash AND sha2(c, 256) = c_hash AND sha2(d, 256) = d_hash
и далее эквивалентно foldLeft
с аккумулятором DataFrame
и ===
. [тысяча сто сорок четыре]
Итак, подведем итог - если C
является набором столбцов, то:
atLeastOneMatch
!atLeastOneMatch
atLeastOneMismatch
!atLeastOneMismatch
[1131 ] Нет, это не так. Рекурсивные запросы поддерживаются в SQL Server после SServer 2005, но не в Access.
Если вы заранее знаете количество уровней, вы можете написать запрос, но он не будет рекурсивным.
В SQL Server Для этого используется CTE (расширение SQL): см. http://blog.crowe.co.nz/archive/2007/09/06/Microsoft-SQL-Server-2005---CTE-Example- of-a-simple.aspx
Однако обычный SQL не имеет поддержки рекурсивности.
Вы не можете рекурсивно запрашивать.
Вы можете сделать произвольное количество левых соединений, но вы ' Я смогу подняться только на столько уровней, сколько у вас есть объединений.
Или вы можете использовать «Модель вложенного набора» Челко , чтобы получить всех родителей. Это потребует изменения структуры таблицы таким образом, чтобы сделать вставки и обновления более сложными.
В Access можно создать запрос, чтобы найти корень вашего заданного задания. Не забывайте о мощи функций VBA .Вы можете создать рекурсивную функцию в модуле VBA и использовать ее результат в качестве поля вывода в своем запросе.
Пример:
Public Function JobRoot(Id As Long, ParentId As Long) As Long
If ParentId = 0 Then
JobRoot = Id
Exit Function
End If
Dim Rst As New ADODB.Recordset
Dim sql As String
sql = "SELECT Id, ParentID FROM JobTable WHERE Id = " & ParentId & ";"
Rst.Open sql, CurrentProject.Connection, adOpenKeyset, adLockReadOnly
If Rst.Fields("ParentID") = 0 Then
JobRoot = Rst.Fields("Id")
Else
JobRoot = JobRoot(Id, Rst.Fields("ParentID")) ' Recursive.
End If
Rst.Close
Set Rst = Nothing
End Function
Вы можете вызвать эту рекурсивную функцию из своего запроса, используя построитель запросов или просто введя имя функции с аргументами в поле запроса.
Это даст корень.
(Я понимаю, что OP исполнился год, но я вынужден ответить, когда все говорят, что невозможное возможно).