Basit tutmak ve bir sorguda birden çok CTE nasıl yapılır


156

Bu basit T-SQL sorgusu var, bir tablodan sütun bir demet yayar ve ayrıca diğer ilgili tablolardan bilgi katılır .

Veri modelim basit. Katılımcılar ile planlanmış bir etkinliğim var. Her etkinliğe kaç katılımcının katıldığını bilmem gerekiyor.

Buna benim çözümüm planlanan etkinlikleri gruplayan ve katılımcı sayısını sayan bir CTE eklemektir.

Bu, planlanan etkinlik başına bu bilgilere katılmamı sağlayacaktır. Sorguyu basit tutma.

Sorgularımı basit tutmayı seviyorum, ancak gelecekte basit sorgum sırasında ek geçici sonuçlara erişebilmem gerekiyorsa ne yapmalıyım?

Birden fazla CTE alabilirsem gerçekten isterdim, ama yapamam, değil mi? Burada benim seçeneklerim neler?

Uygulama veri katmanında görünümleri ve işleri yapmayı reddettim. SQL sorgularımı izole etmeyi tercih ederim.

Yanıtlar:


298

CTEBir sorguda birden çok s olabilir ve aşağıdakileri tekrar kullanabilirsiniz 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

Ancak, bu SQL Serveryeniden değerlendirmek olabilir CTEsizin gibi değerleri kullanıyorsanız, bu durumda onu erişilen her zaman RAND(), NEWID()vb, bunlar arasında değişebilir CTEaramalar.


3
Bu kadar basitti. MSDN belgeleri sorun etrafında biraz bulanık, kesin bir şey bulamadık. Çok teşekkür ederim!
John Leidegren

1
Common_table_expression (Transact-sql) ile belgelenmiştir . Bunu (özel dikkat çekmek sözdizimi bölümünde bulunmaktadır görebilirsiniz [ ,...n ]in [ WITH <common_table_expression> [ ,...n ] ]açıkça bu sesleniyor "tek bir sorguda birden CTE tanımlarını kullanma". Örnek C,. Ne yazık ki, bu örnek SQL 2008 ve belgelerinde sağlanmaz daha eski (yani, OP soruyu yayınladığında örnek sağlanmadı)
Brian

Bu kayıtların miktarını iki katına
çıkıyorum

@TomStickel, sorgunun yarısını yalnızca sondan önce kullanmayı deneyinUNION ALL
Quassnoi

@Quassnoi Evet işe yaradı. Yorum yazdıktan sonra bunu yaptım. 2. birliğin neden orada olduğundan emin değilim ...
Tom Stickel

90

Kesinlikle tek bir sorgu ifadesinde birden çok CTE'ye sahip olabilirsiniz. Onları virgülle ayırmanız yeterlidir. İşte bir örnek. Aşağıdaki örnekte iki CTE vardır. Biri adlandırılır CategoryAndNumberOfProductsve ikincisi adlandırılır 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

5
@JohnLeidegren: İlk doğru cevaptan sonraki 2 dakika içinde doğru bir cevap göndermek, en azından verdiğim bir oylamayı hak ediyor.
Peter Majeed
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.