При правильной комбинации $ lookup, $ project и $ match вы можете присоединиться к нескольким таблицам по нескольким параметрам. Это связано с тем, что они могут быть связаны несколько раз.
Предположим, что мы хотим сделать следующее ( reference )
SELECT S.* FROM LeftTable S
LEFT JOIN RightTable R ON S.ID =R.ID AND S.MID =R.MID WHERE R.TIM >0 AND
S.MOB IS NOT NULL
Шаг 1: Свяжите все таблицы
, вы можете $ lookup сколько угодно таблиц.
$ lookup - по одному для каждой таблицы в запросе
$ unwind - поскольку данные денормализированы правильно, иначе они завернуты в массивы
Python code ..
db.LeftTable.aggregate([
# connect all tables
{"$lookup": {
"from": "RightTable",
"localField": "ID",
"foreignField": "ID",
"as": "R"
}},
{"$unwind": "R"}
])
Шаг 2: Определите все условные выражения
$ project: определите здесь все условные операторы и все переменные, которые вы хотите выбрать.
Python Code ..
db.LeftTable.aggregate([
# connect all tables
{"$lookup": {
"from": "RightTable",
"localField": "ID",
"foreignField": "ID",
"as": "R"
}},
{"$unwind": "R"},
# define conditionals + variables
{"$project": {
"midEq": {"$eq": ["$MID", "$R.MID"]},
"ID": 1, "MOB": 1, "MID": 1
}}
])
Шаг 3: Присоедините все условные обозначения
$ match - присоедините все условия, используя OR или AND и т. д. Их могут быть кратные ,
$ project: undefine all conditionals
Python Code ..
db.LeftTable.aggregate([
# connect all tables
{"$lookup": {
"from": "RightTable",
"localField": "ID",
"foreignField": "ID",
"as": "R"
}},
{"$unwind": "$R"},
# define conditionals + variables
{"$project": {
"midEq": {"$eq": ["$MID", "$R.MID"]},
"ID": 1, "MOB": 1, "MID": 1
}},
# join all conditionals
{"$match": {
"$and": [
{"R.TIM": {"$gt": 0}},
{"MOB": {"$exists": True}},
{"midEq": {"$eq": True}}
]}},
# undefine conditionals
{"$project": {
"midEq": 0
}}
])
Практически любая комбинация таблиц, условных обозначений и объединений может быть выполнена таким образом ,
Вы можете использовать модуль %
, чтобы получить дополнительные шары.
Пример фрагмента:
select *, coalesce(floor(Overs)*6 + floor((Overs%1)*10), 0) as Balls
from (values
(1.0),
(4.0),
(4.5),
(null)
) as v(Overs);
Тест на db <> fiddle здесь
[ 1110] Результат:
Overs Balls
----- -----
1.0 6
4.0 24
4.5 29
NULL 0
На основании вашего последнего комментария мы можем сначала FLOOR
повторить, чтобы найти, каким будет первый множитель.
Затем мы вычитаем из этого значение, конвертируем в INT и добавляем.
declare @over decimal(4,1) = 4.5
select
SixeTimesThis = floor(@over)
,Remainder = (@over - floor(@over))
,RemainderAsInt = cast(replace((@over - floor(@over)),'.','') as int)
,FinalResult = floor(@over) * 6 +cast(replace((@over - floor(@over)),'.','') as int)