Извлечение полей из вложенных подзапросов больше второго уровня

publexus
Дата: 19.01.2009 18:41:36
Есть такой, например, запросик:
SELECT COMPANY_CODE,WAREHOUSE, PART_CODE,
	BEST_BEFORE,
	IC_RETEST_DATE = CASE WHEN(BEST_BEFORE>DATEADD(MONTH,1,GETTIME())) THEN BEST_BEFORE ELSE DATEADD(MONTH,1,GETTIME()) END
FROM
	(SELECT COMPANY_CODE,WAREHOUSE, PART_CODE,
		BEST_BEFORE = CASE WHEN(BEST_BEFORE>GETTIME()) THEN BEST_BEFORE ELSE GETTIME()
	FROM
		(SELECT COMPANY_CODE, WAREHOUSE, PART_CODE,
			DATEADD(DAY,CREATE_DATE,SHELF_LIFE) BEST_BEFORE
		 FROM PRODUCT_MASTER
			WHERE ACTIVE_STATUS='A'
		) T1
	WHERE BEST_BEFORE BETWEEN YEAR(GETDATE()) AND YEAR(GETDATE())+1
	) T2
Особо в смысл запроса вдаваться не стоит, это пример, и его алгоритм не имеет значения. Просто хочу обратить внимание на один момент: есть несколько вложенных друг в друга подзапросов, и в каждом подзапросе, начиная с самого внутреннего, в родительский запрос передается один и тот же набор полей (COMPANY_CODE, WAREHOUSE, PART_CODE), которые не изменяются, остальные поля участвуют в вычислениях на каждом этапе. У меня такой вопрос: можно ли передавать поля из самого внутреннего запроса в самый верхний, не перечисляя их каждый раз в дочернем запросе, чтобы передать в родительский и т.д.? При попытке сделать это в лоб выдается ошибка "The multi-part identifier "T1.COMPANY_CODE" could not be bound.". Есть ли обходные пути, никто не пытался решить эту проблему?
Паганель
Дата: 19.01.2009 18:44:11
publexus
можно ли передавать поля из самого внутреннего запроса в самый верхний,
не перечисляя их каждый раз в дочернем запросе, чтобы передать в родительский и т.д.?
А почему бы и не перечислить?
Не вижу причин...
Mr Marmelad
Дата: 19.01.2009 18:44:53
Даже если Вы и найдёте такие пути - рекомендациями будет не пользоваться ими - Держите объём выводимых данных всегда под контролем Коллега - просто практика. Best Practice
publexus
Дата: 19.01.2009 19:01:04
Паганель
publexus
можно ли передавать поля из самого внутреннего запроса в самый верхний,
не перечисляя их каждый раз в дочернем запросе, чтобы передать в родительский и т.д.?
А почему бы и не перечислить?
Не вижу причин...

Можно и перечислить, а можно и попытаться найти, возможно, более красивое решение. Ведь на самом деле можно было в данном запросе и не делать вложенности, написав все одним выражением, но тогда сложность этого выражения была бы геометрически пропорциональна количеству вложенных запросов. Если есть идеи, то озвучьте, пожалуйста! Если есть критика, то критикуйте или делайте замечания. Буду рад услышать мнения.
Паганель
Дата: 19.01.2009 19:12:07
Попытаюсь от обратного
Представим, что у Вас в самом внешнем FROM соединено две derived table (назовем их T2 и T3)
А внутри каждой из них - еще по одной derived table, и обе вполне законно могут называться T1
И если в самом внешнем запросе указать T1.COMPANY_CODE, то сервер просто не будет понимать - а из какого именно T1 ему брать данные

То есть вот такой вот совершенно идиотский (но с точки зрения синтаксиса - не ошибочный) запрос
SELECT T2.COMPANY_CODE,T2.WAREHOUSE, T3.PART_CODE,	T3.BEST_BEFORE,
	IC_RETEST_DATE = CASE WHEN(T2.BEST_BEFORE>DATEADD(MONTH,1,GETTIME())) 
        THEN T2.BEST_BEFORE ELSE DATEADD(MONTH,1,GETTIME()) END
,T1.COMPANY_CODE
FROM
	(SELECT COMPANY_CODE,WAREHOUSE, PART_CODE,
		BEST_BEFORE = CASE WHEN(BEST_BEFORE>GETTIME()) THEN BEST_BEFORE ELSE GETTIME()
	FROM
		(SELECT COMPANY_CODE, WAREHOUSE, PART_CODE,
			DATEADD(DAY,CREATE_DATE,SHELF_LIFE) BEST_BEFORE
		 FROM PRODUCT_MASTER
			WHERE ACTIVE_STATUS='A'
		) T1
	WHERE BEST_BEFORE BETWEEN YEAR(GETDATE()) AND YEAR(GETDATE())+1
	) T2
cross join
	(SELECT COMPANY_CODE,WAREHOUSE, PART_CODE,
		BEST_BEFORE = CASE WHEN(BEST_BEFORE>GETTIME()) THEN BEST_BEFORE ELSE GETTIME()
	FROM
		(SELECT COMPANY_CODE, WAREHOUSE, PART_CODE,
			DATEADD(DAY,CREATE_DATE,SHELF_LIFE) BEST_BEFORE
		 FROM PRODUCT_MASTER
			WHERE ACTIVE_STATUS='B'
		) T1
	WHERE BEST_BEFORE BETWEEN YEAR(GETDATE())+1 AND YEAR(GETDATE())+2
	) T3