[MSSQL2000] Никак запрос не сочиню

Работа VB и СУБД (Access, MSSQL, MySQL, Oracle и пр.)
Правила форума
При создании новой темы не забывайте указывать используемую СУБД.
alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

[MSSQL2000] Никак запрос не сочиню

Сообщение alibek » 22.07.2006 (Сб) 14:08

Что-то не выходит каменный цветок.

Есть у меня таблица, допустим tableA. Есть другая таблица, tableB, связанная с первой как 1:M.
В таблице tableB есть два поля, Order и Flag.
Есть также третья таблица, res, в которой часть полей уже заполнена, а другую часть надо извлечь из tableA и tableB.
Причем, одной записи в res может соответствовать одна запись в A и несколько записей в B (т.к. 1:M), в этом случае из B надо взять только одну запись, с Flag=1, если таковые есть, или с минимальным Order в другом случае.

По идее, запрос должен быть таким:
Код: Выделить всё
UPDATE res
SET ...
FROM res
JOIN tableA A ON A.InstanceID = res.InstanceID
LEFT JOIN (SELECT TOP 1 ... FROM tableB WHERE [InstanceID] = A.InstanceID ORDER BY CASE [Flag] WHEN 1 THEN 1 ELSE 2 END, [Order]) B ON B.InstanceID = A.InstanceID

В теории правильно, на практике выходит ошибка, что A не соответствует таблице или альясу, используемому в запросе. Очевидно, в MSSQL подзапросы не ведают о вышестоящей информации.
Как бы это обойти?
Последний раз редактировалось alibek 22.07.2006 (Сб) 16:45, всего редактировалось 1 раз.
Lasciate ogni speranza, voi ch'entrate.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 22.07.2006 (Сб) 15:43

JOIN tableA A ON A.InstanceID ON res.InstanceID

Э... INNER JOIN tableA A ON A.InstanceID = res.InstanceID
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 22.07.2006 (Сб) 16:53

Это опечатка, конечно же вместо второго ON было =
Lasciate ogni speranza, voi ch'entrate.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 22.07.2006 (Сб) 17:11

А...
Хм...

Код: Выделить всё
UPDATE res
SET foo = a.foo
FROM
  res
  INNER JOIN tableA AS a ON a.InstanceID = res.InstanceID
  LEFT JOIN tableB AS b
    ON
      b.InstanceID = a.InstanceID
      AND (b.Flag = 1 OR b.[Order] = (SELECT MIN([Order]) FROM TableB WHERE InstanceID = a.InstanceID AND Flag <> 1))

Не? :roll:
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Re: [MSSQL2000] Никак запрос не сочиню

Сообщение Ennor » 23.07.2006 (Вс) 17:34

alibek писал(а):Очевидно, в MSSQL подзапросы не ведают о вышестоящей информации.
Ведают, почему же - коррелированные подзапросы в сиквеле есть уже очень давно... Просто такие вещи надо выносить из секции FROM:
Код: Выделить всё
select ...,
  (SELECT TOP 1 ... FROM tableB
  WHERE [InstanceID] = A.InstanceID ORDER BY CASE [Flag] WHEN 1 THEN 1 ELSE 2 END, [Order]) as [tableB_Column]
FROM res
  inner JOIN tableA A ON A.InstanceID = res.InstanceID

Тут, правда, ограничение - ЕМНИП, в таком вложенном подзапросе может возвращаться только один столбец, т.к. тебе для него алиас нужно обязательно указать. Иначе... Иначе, подозреваю, в один запрос это сделать не получится. Ну или получится, в конечном итоге, но по эффективности будет хуже, чем несколько стадий с времянкой или табличной переменной :).


Вернуться в Базы данных

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3

    TopList