Как найти несоответствующие n-ые дочерние строки по имени? - PullRequest
1 голос
/ 30 апреля 2019

Я пытаюсь написать запрос, чтобы найти n-ые дочерние записи, только если n-ые дочерние записи не совпадают по имени.

Упрощенная структура данных:

  • Root (PK: id)
    • Job (PK: id, FK: idRoot -> Root.id)
      • Task (PK: id, FK: idParent -> Job.id, FK:idRoot -> Root.id)

Все поля идентификаторов являются строками (меня интересует текущий дизайн, менять его не нам)

Идея состоит в том, что подзапрос получит только одно совпадение для каждого корня, и они будут оцениваться по сравнению с другим совпадением из других корней.Если все результаты из подзапроса не совпадают (в указанной строке), все они не будут выполнены.По сути, мне нужно, чтобы все n-ые задачи имели одинаковое имя для всех выбранных корней, иначе все они не будут выполнены.

У меня есть запрос, который дает мне каждую n-ю дочернюю запись для каждого корня (где Task - это дочерняя таблица).Однако я не могу понять, как проверить на равенство.Кроме того, это необходимо для работы как с SQL Compact, так и с SQL Server, что ограничивает некоторые функции.

Это для n = 1 (первая задача)

SELECT COUNT(r.id) as RowIndex, t.id, t.idRoot, t.Name
FROM Task t
  INNER JOIN Job j ON j.id = t.idParent
  INNER JOIN (
    SELECT b.id, b.idParent, b.idRoot, b.StartDate
    FROM Task b
      INNER JOIN Job c ON b.idParent = c.idRec
  ) r ON t.StartDate >= r.StartDate
      AND r.idParent = j.id 
      AND t.idRoot = r.idRoot
WHERE t.idRoot IN ('1', '2', '3', '4')
  AND j.Type LIKE '%Example%'
GROUP BY t.idRoot, t.id, t.Name
HAVING COUNT(r.id) = 1    

Это возвращает мне что-то вроде:

╔══════════╦════╦════════╦════════════╗
║ RowIndex ║ ID ║ IDRoot ║    Name    ║
╠══════════╬════╬════════╬════════════╣
║        1 ║  4 ║      2 ║ 1st Task   ║
║        1 ║  7 ║      3 ║ 1st Task   ║
║        1 ║ 11 ║      4 ║ First Task ║
╚══════════╩════╩════════╩════════════╝

Итак, в приведенных выше результатах я правильно получаю первое задание из типов заданий «Пример».Я не могу понять, как получить результаты только тогда, когда имена не все совпадают.Если каждое из имен было «1-й задачей», запрос не должен возвращать ничего.

ОБНОВЛЕНИЕ:

Вот ссылка , чтобы вставить этоМожно создавать таблицы и загружать данные образца.

Запрос A возвращает первое задание для типа задания A, а результаты показывают, что имена заданий не совпадают.Поэтому я хотел бы, чтобы оба идентификатора задачи были возвращены.

Запрос B возвращает первые задачи для типа задания B, а результаты показывают совпадение всех имен задач.Поэтому я бы не хотел возвращать ни один из этих идентификаторов задач.

1 Ответ

1 голос
/ 30 апреля 2019

Попробуйте использовать следующий запрос:


SELECT 
r.ID 
, j.TYPE 
, t.Name 
, t.StartDate 
INTO #CoreData 
FROM root r 
INNER JOIN job j 
ON j.idRoot = r.id 
INNER JOIN task t 
ON t.idParent = j.id 
AND t.idRoot = r.id 

SELECT 
c.ID 
, c.Name 
, c.StartDate 
, c.TYPE 
, x.RowID 
INTO #CoreDataWithRowID 
FROM #CoreData c 
CROSS APPLY ( 
SELECT 
COUNT(*) AS RowID 
FROM #CoreData cd 
WHERE cd.TYPE = c.TYPE 
AND cd.ID = c.ID 
AND cd.StartDate <= c.StartDate 
) x 


SELECT 
oa.* 
FROM #CoreDataWithRowID oa 
INNER JOIN #CoreDataWithRowID ob 
ON oa.TYPE = ob.TYPE 
AND oa.RowID = ob.RowID 
AND oa.ID <= ob.ID 
WHERE oa.Name != ob.Name 
UNION 
SELECT 
oa.* 
FROM #CoreDataWithRowID oa 
INNER JOIN #CoreDataWithRowID ob 
ON oa.TYPE = ob.TYPE 
AND oa.RowID = ob.RowID 
AND oa.ID >= ob.ID 
WHERE oa.Name != ob.Name

Надеемся, что это обойдет некоторые ограничения, вызванные SQL Server Compact Edition.

...