Несколько операторов выбора с использованием SQL Server 2005 "WITH" Statement

Я пытаюсь использовать оператор "WITH" в SQL Server 2005. Кажется, он работает нормально, если я делаю что-то вроде:

WITH MyBigProducts AS (SELECT * FROM Products WHERE Size='Big')
SELECT Name FROM MyBigProducts

Но это терпит неудачу, если я пытаюсь использовать несколько операторов выбора, например:

WITH MyBigProducts AS (SELECT * FROM Products WHERE Size='Big')
SELECT Name FROM MyBigProducts
SELECT Count(*) FROM MyBigProducts

и сообщение об ошибке: "Недопустимое имя объекта" MyBigProducts ".

Есть ли что-то, что я могу сделать, чтобы увеличить объем таблицы "MyBigProducts", чтобы включить оба оператора select?

Мой пример - это упрощение моего фактического кода, вызывающего проблему, поэтому я не обесцениваю возможность того, что приведенный выше тривиальный пример должен работать, и что в моем SQL есть еще одна ошибка.

Я попытался обернуть BEGIN и END вокруг двух операторов SELECT, но синтаксический анализатор не смог его скомпилировать.

Ответы

Ответ 1

Как сказал Кейн, CTE доступен только в инструкции SQL, где он написан. Другим возможным решением, в зависимости от специфики вашей ситуации, было бы включение COUNT (*) в один запрос:

;WITH MyBigProducts AS
(
     SELECT
          Name,
          COUNT(*) OVER () AS total_count
     FROM
          Products
     WHERE
          Size = 'Big'
)
SELECT
     Name,
     total_count
FROM
     MyBigProducts

Ответ 2

Я считаю, что общие выражения таблицы действительны только для немедленного использования, поэтому вы получаете сообщение об ошибке "SELECT Count (*) FROM MyBigProducts". Чтобы повторно использовать CTE, вместо этого вы должны использовать временную таблицу.

DECALRE @BigProducts TABLE (...[declaration omitted]...)

INSERT INTO @BigProducts
SELECT * 
FROM Products 
WHERE Size='Big'


SELECT Name FROM @BigProducts
SELECT Count(*) FROM @BigProducts

Пожалуйста, поправьте меня, если я ошибаюсь.

Ответ 3

CTE имеет локальную область видимости и видимость оператора. Если вы хотите увеличить масштаб и видимость для выражения таблицы, вам нужно сделать CTE в функцию View или table-value.

В качестве альтернативы вы можете материализовать результаты выражений в табличной переменной, которая является локальной для текущей партии или временной таблицы, время жизни которой также является локальной для текущей партии, но чья видимость распространяется на весь сеанс.

Ответ 4

CREATE TABLE tblEmployees
(
    EmployeeID    SMALLINT IDENTITY(1001,1) NOT NULL,
    EmployeeName  NVARCHAR(100) NOT NULL,
    Department    NVARCHAR(50) NOT NULL,
    Designation   NVARCHAR(50) NOT NULL,
    JoiningDate   DATETIME NOT NULL,
    Salary        DECIMAL(10,2) NOT NULL,
    [Description] NVARCHAR(1000) NULL 
)

SELECT * FROM tblEmployees

INSERT INTO tblEmployees(EmployeeName, Department, Designation, JoiningDate, Salary, [Description]) 
VALUES  ('John Smith', 'IT Research', 'Research Analyst', '02/08/2005', 23000.00, 'John Smith is involved in the Research and Development since 2005')

INSERT INTO tblEmployees(EmployeeName, Department, Designation, JoiningDate, Salary, [Description]) 
VALUES  ('John Micheal', 'IT Operations', 'Manager', '07/15/2007', 15000.00, NULL)

INSERT INTO tblEmployees(EmployeeName, Department, Designation, JoiningDate, Salary, [Description]) 
VALUES  ('Will Smith', 'IT Support', 'Manager', '05/20/2006', 13000.00, 'Joined this year as IT Support Manager')

INSERT INTO tblEmployees(EmployeeName, Department, Designation, JoiningDate, Salary, [Description]) 
VALUES  ('Anna John', 'IT Support', 'Developer', '02/10/2008', 23000.00, 'Joined this year as IT Support Developer')


DECLARE @EmpID AS SMALLINT
DECLARE @SQLQuery AS NVARCHAR(500)
SET @EmpID = 1001
SET @SQLQuery = 'SELECT * FROM tblEmployees WHERE EmployeeID = ' + CAST(@EmpID AS NVARCHAR(10))
Print @SQLQuery 
EXECUTE(@SQLQuery)


DECLARE @EmpID AS SMALLINT
DECLARE @SQLQuery AS NVARCHAR(500)
DECLARE @ParameterDefinition AS NVARCHAR(100)
SET @EmpID = 1002
SET @SQLQuery = 'SELECT * FROM tblEmployees WHERE EmployeeID = @EmpID' 
SET @ParameterDefinition =  '@EmpID SMALLINT'
EXECUTE sp_executesql @SQLQuery, @ParameterDefinition, @EmpID



Create Procedure sp_EmployeeSelect
    @EmployeeName NVarchar(100),
    @Department NVarchar(50),
    @Designation NVarchar(50),
    @StartDate DateTime,
    @EndDate DateTime,
    @Salary Decimal(10,2)       
AS
    Set NoCount ON  
    Declare @SQLQuery AS NVarchar(4000)
    Declare @ParamDefinition AS NVarchar(2000) 
    Set @SQLQuery = 'Select * From tblEmployees where (1=1) ' 

    If @EmployeeName Is Not Null 
         Set @SQLQuery = @SQLQuery + ' And (EmployeeName = @EmployeeName)'
    If @Department Is Not Null
         Set @SQLQuery = @SQLQuery + ' And (Department = @Department)' 
    If @Designation Is Not Null
         Set @SQLQuery = @SQLQuery + ' And (Designation = @Designation)'
    If (@StartDate Is Not Null) AND (@EndDate Is Not Null)
         Set @SQLQuery = @SQLQuery + ' And (JoiningDate BETWEEN @StartDate AND @EndDate)'
    If @Salary Is Not Null
         Set @SQLQuery = @SQLQuery + ' And (Salary >= @Salary)'
    Set @ParamDefinition = '@EmployeeName NVarchar(100),
                @Department NVarchar(50),
                @Designation NVarchar(50),
                @StartDate DateTime,
                @EndDate DateTime,
                @Salary Decimal(10,2)'

    Exec sp_Executesql  @SQLQuery, @ParamDefinition, @EmployeeName, @Department, @Designation, 
                        @StartDate, @EndDate, @Salary

    If @@ERROR <> 0 GoTo ErrorHandler
    Set NoCount OFF
    Return(0)

ErrorHandler:
    Return(@@ERROR)
GO


EXEC sp_EmployeeSelect 'John Smith', NULL, NULL, NULL, NULL, NULL

EXEC sp_EmployeeSelect NULL, 'IT Operations', 'Manager', NULL, NULL, NULL




DECLARE @EmpName AS NVARCHAR(50)
DECLARE @SQLQuery AS NVARCHAR(500)
SET @EmpName = 'John' 
SET @SQLQuery = 'SELECT * FROM tblEmployees WHERE EmployeeName LIKE '''+ '%' + @EmpName + '%' + '''' 
PRINT @SQLQuery
EXECUTE sp_executesql @SQLQuery



DECLARE @EmpID AS NVARCHAR(50)
DECLARE @SQLQuery AS NVARCHAR(500)
SET @EmpID = '1001,1003,1004,1002' 
SET @SQLQuery = 'SELECT * FROM tblEmployees WHERE EmployeeID IN(' + @EmpID + ')'
EXECUTE sp_executesql @SQLQuery


DECLARE @OrderBy AS NVARCHAR(50)
DECLARE @SQLQuery AS NVARCHAR(500)
SET @OrderBy = 'Department' 
SET @SQLQuery = 'SELECT * FROM tblEmployees Order By ' + @OrderBy
EXECUTE sp_executesql @SQLQuery


WITH RESULTS AS(
SELECT * FROM [dbo].[User]
)`enter code here`

Ответ 5

WITH n(id, name) AS 
   (SELECT id, name 
    FROM ABC
    WHERE parent = 44
        UNION ALL
    SELECT m.id, m.name 
    FROM ABC as m, n
    WHERE n.id = m.parent)
SELECT * FROM n