#sql-server #tsql #sql-server-2019
Вопрос:
Извините за длинное название, мне было трудно описать то, что я пытаюсь сделать. Это просто понять, как вы увидите ниже, но трудно обобщить в название.
У меня есть запрос, который возвращает следующие данные:
| ParentID | ChildID | Flag |
| 100 | 1 | 0 |
| 100 | 1 | 1 |
| 100 | 2 | 0 |
| 100 | 2 | 0 |
| 200 | 1 | 1 |
| 200 | 1 | 1 |
В столбце флаг будет только 1 или 0.
Мне нужно отфильтровать результаты так, чтобы для каждой комбинации родитель/потомок была только одна строка.
Флаг должен быть равен 1, если в полном наборе результатов выше была одна или несколько записей, где для комбинации родитель/потомок было 1, в противном случае он должен быть равен нулю.
Таким образом, результат, если применить его к вышесказанному, будет:
| ParentID | ChildID | Flag |
| 100 | 1 | 1 |
| 100 | 2 | 0 |
| 200 | 1 | 1 |
У меня это работает только с колонками childID и Flag:
DECLARE @InMemoryResultsFirstPass AS TABLE (ChildID Integer, Flag Integer)
DECLARE @InMemoryResultsRecs AS TABLE (ChildID Integer, Flag Integer)
INSERT INTO @InMemoryResultsFirstPass
SELECT 1 ChildID, 0 Flag
UNION SELECT 1 ChildID, 1 Flag
UNION SELECT 2 ChildID, 0 Flag
UNION SELECT 2 ChildID, 0 Flag
UNION SELECT 1 ChildID, 1 Flag
UNION SELECT 1 ChildID, 1 Flag
select * from @InMemoryResultsFirstPass
INSERT INTO @InMemoryResultsRecs
SELECT DISTINCT
result.*
FROM @InMemoryResultsFirstPass imr
CROSS APPLY (
SELECT TOP 1
*
FROM @InMemoryResultsFirstPass imrfp
WHERE imrfp.ChildID = imr.ChildID
ORDER BY imrfp.Flag DESC
) result
select * from @InMemoryResultsRecs
Но я не смог понять, как это сделать, как только я добавлю это в столбец ParentID. Я попробовал несколько разных подходов, пытаясь выполнить вложенный запрос в ПЕРЕКРЕСТНОМ ПРИМЕНЕНИИ с ГРУППОЙ по родительскому идентификатору, но независимо от того, что я пытаюсь, я теряю родительский идентификатор = 200 записей:
DECLARE @InMemoryResultsFirstPass AS TABLE (ParentID Integer, ChildID Integer, Flag Integer)
DECLARE @InMemoryResultsRecs AS TABLE (ParentID Integer, ChildID Integer, Flag Integer)
INSERT INTO @InMemoryResultsFirstPass
SELECT 100 ParentID, 1 ChildID, 0 Flag
UNION SELECT 100 ParentID, 1 ChildID, 1 Flag
UNION SELECT 100 ParentID, 2 ChildID, 0 Flag
UNION SELECT 100 ParentID, 2 ChildID, 0 Flag
UNION SELECT 200 ParentID, 1 ChildID, 1 Flag
UNION SELECT 200 ParentID, 1 ChildID, 1 Flag
select * from @InMemoryResultsFirstPass
INSERT INTO @InMemoryResultsRecs
SELECT DISTINCT
result.*
FROM @InMemoryResultsFirstPass imr
CROSS APPLY (
SELECT TOP 1
*
FROM @InMemoryResultsFirstPass imrfp
WHERE imrfp.ChildID = imr.ChildID
ORDER BY imrfp.Flag DESC
) result
select * from @InMemoryResultsRecs
Любая помощь будет весьма признательна.
Спасибо, что уделили мне время.
Комментарии:
1. это просто
SELECT ParentID, ChildID, MAX(Flag) FROM table GROUP BY ParentID, ChildID
так ?2. @Белка спасибо за ответ. В колледже мне показали ту же технику, прежде чем я увидел это. 😉
Ответ №1:
На самом деле, я только что разобрался в этом:
SELECT ParentID, ChildID, MAX(Flag) AS Flag
FROM @InMemoryResultsFirstPass
GROUP BY ParentID, ChildID
ORDER BY ParentID, ChildID
Надеюсь, это поможет кому-то еще: -)
Комментарии:
1. Хорошая работа! Есть куча разных способов сделать это, этот может быть самым простым.