views:

80

answers:

2

I have this simple T-SQL query, it emits a bunch of columns from a table and also joins information from other related tables.

My data model is simple. I have a scheduled event, with participants. I need to know how many participants participate in each event.

My solution to this is to add a CTE that groups scheduled events and counts the number of participants.

This will allow me to join in that information per scheduled event. Keeping the query simple.

I like to keep my queries simple, however, If I ever in the future need to have additonal temporary results accessible during my simple query, what do I do?

I would really like it, if I could have multiple CTEs but I can't, right? What are my options here?

I've ruled out views and doing things at the application data layer. I prefer to isolated my SQL queries.

+4  A: 

You can have multiple CTE's in one query, as well as you can reuse a CTE:

WITH    cte1 AS
        (
        SELECT  1 AS id
        ),
        cte2 AS
        (
        SELECT  2 AS id
        )
SELECT  *
FROM    cte1
UNION ALL
SELECT  *
FROM    cte2
UNION ALL
SELECT  *
FROM    cte1

Note, however, that SQL Server may reevaluate the CTE each time it is accessed, so if you are using values like RAND(), NEWID() etc., they may change between the CTE calls.

Quassnoi
It was that simple. the MSDN documentation was a bit fuzzy around the issue, I couldn't find anything conclusive. Thank you very much!
John Leidegren
A: 

You certainly are able to have multiple CTE's in a single query expression. You just need to separate them with a comma. Here is an example. Please pardon the formatting. I don't quite have the hang of formatting on StackOverflow yet. In the example below, there are two CTE's. One is named CategoryAndNumberOfProducts and the second is named ProductsOverTenDollars.

WITH CategoryAndNumberOfProducts (CategoryID, CategoryName, NumberOfProducts) AS
(
   SELECT
      CategoryID,
      CategoryName,
      (SELECT COUNT(1) FROM Products p
       WHERE p.CategoryID = c.CategoryID) as NumberOfProducts
   FROM Categories c
),

ProductsOverTenDollars (ProductID, CategoryID, ProductName, UnitPrice) AS
(
   SELECT
      ProductID,
      CategoryID,
      ProductName,
      UnitPrice
   FROM Products p
   WHERE UnitPrice > 10.0
)

SELECT c.CategoryName, c.NumberOfProducts,
      p.ProductName, p.UnitPrice
FROM ProductsOverTenDollars p
   INNER JOIN CategoryAndNumberOfProducts c ON
      p.CategoryID = c.CategoryID
ORDER BY ProductName
Randy Minder
Thanks for the input, but why did you post a redundant answer? Quassnoi has already provided me with this information. You should remove this answer. SO (stackoverflow) is quite heavily moderated and my stand towards answers is that if they don't add something new, they should be avoided. Up vote the question or Quassnoi ansers if you liked the question or the answer instead.
John Leidegren
@John - What makes you think I knew what Quassnoi had posted? Looking at the times of posting, he and I posted an answer at about the same time. I answer a lot of questions. After I answer one, I don't go back to each one and check to make sure someone didn't post a similar answer a few seconds or minutes before mine.
Randy Minder