Как выбрать из части таблицы, выбранной ранее

#sql #sql-server #select

#sql #sql-сервер #выберите

Вопрос:

Поскольку я собираю данные со связанного сервера insql, я должен выбрать часть таблицы и должен работать с ней. Но когда я хочу сделать условный выбор из вложенной таблицы, я получаю сообщение «Ошибка недопустимого имени объекта», чего не должно быть, потому что я устанавливаю его с помощью «AS»

     SELECT * from (
    SELECT * FROM [Runtime].[dbo].[History]
    where TagName like '%L8.CipPhase%' and DateTime >= DATEADD(HOUR, -12, GETDATE())
    ) as t 
    WHERE t.[DateTime] >= 
    (SELECT MAX(t.[DateTime]) FROM t
    where TagName like '%L8.CipPhase%' and t.[DateTime] < 
    (SELECT MAX(t.[DateTime]) from t
    where TagName like '%L8.CipPhase%' and t.Value = 0))
  

Комментарии:

1. Я уверен, что есть более простой способ выразить этот запрос. Вам следует задать другой вопрос с примерами данных, желаемыми результатами и объяснением того, чего вы пытаетесь достичь.

Ответ №1:

Вы ссылаетесь на t, который создается как псевдоним из подзапроса, в 2 дополнительных подзапросах как таблицы в предложении FROM — это недопустимо, он считает t , что существует реальное имя таблицы. Чтобы использовать его таким образом, вам нужно будет создать общее табличное выражение (CTE).

например

 With t as (
    SELECT * FROM [Runtime].[dbo].[History]
    where TagName like '%L8.CipPhase%' and DateTime >= DATEADD(HOUR, -12, GETDATE())
)
    SELECT * from t
    WHERE t.[DateTime] >=  (
                            SELECT MAX(t.[DateTime]) 
                            FROM t
                            where TagName like '%L8.CipPhase%' 
                            and t.[DateTime] < (
                                 SELECT MAX(t.[DateTime]) 
                                 from t
                                 where TagName like '%L8.CipPhase%' 
                                 and t.Value = 0
                            )
    )
  

Ответ №2:

используйте временную таблицу :

 SELECT * into #Temp FROM [Runtime].[dbo].[History]
where TagName like '%L8.CipPhase%' and DateTime >= DATEADD(HOUR, -12, GETDATE())
declare @DateTime DateTime


SELECT @DateTime=MAX(t.[DateTime]) 
FROM #Temp
where TagName like '%L8.CipPhase%' and t.[DateTime] < 
(SELECT MAX(t.[DateTime]) from #Temp
where TagName like '%L8.CipPhase%' and t.Value = 0)    

select * from #Temp 
    WHERE t.[DateTime] >= @DateTime
  

Ответ №3:

T — это не таблица, это псевдоним для подзапроса. Итак, в условии where вам необходимо указать имя таблицы, из которой вы извлекаете максимальную дату.

    SELECT * from (
    SELECT * FROM [Runtime].[dbo].[History]
    where TagName like '%L8.CipPhase%' and DateTime >= DATEADD(HOUR, -12, GETDATE())
    ) as t 
    WHERE t.[DateTime] >= 
    (SELECT MAX(t.[DateTime]) FROM [Runtime].[dbo].[History] t
    where TagName like '%L8.CipPhase%' and DateTime >= DATEADD(HOUR, -12, GETDATE() and t.[DateTime] < 
    (SELECT MAX(t.[DateTime]) from [Runtime].[dbo].[History] t
    where TagName like '%L8.CipPhase%' and DateTime >= DATEADD(HOUR, -12, GETDATE() and t.Value = 0))
  

Комментарии:

1. Если вы просто измените псевдоним t на исходную таблицу, предикат вложенного запроса DateTime >= DATEADD(HOUR, -12, GETDATE()) не будет включен в его дальнейшее использование. Намерение, по-видимому, заключается в повторном использовании, поэтому предикат также должен быть включен.

2. Отмечено, что использование CTE является эффективным способом, но это альтернативный вариант, я также включил соответствующее условие where.