2014-06-17 18 views
9

Let ben masa #Foo söylüyorlarnasıl bir ZIP T-SQL JOIN uygulamak?</p> <pre><code>Id Color -- ---- 1 Red 2 Green 3 Blue 4 NULL </code></pre> <p>Ve tablo #bar:

Value 
----- 
1 
2.5 

benim hemen basit deyimi kullanarak tablo Sonucu oluşturmak istiyorum:

Id Color Value 
-- ---- ----- 
1 Red 1 
2 Green 2.5 
3 Blue NULL 
4 NULL NULL 

neler Şimdiye kadar icat geçerli:

WITH cte1 
AS 
(
    SELECT [Id], [Color], ROW_NUMBER() OVER (ORDER BY [Id]) AS 'No' 
    FROM #Foo 
), 
cte2 
AS 
(
    SELECT [Value], ROW_NUMBER() OVER (ORDER BY [Value]) AS 'No' 
    FROM #Bar 
) 
SELECT [Id], [Color], [Value] 
FROM cte1 c1 
FULL OUTER JOIN cte2 c2 ON c1.[No] = c2.[No] 

daha hızlı veya ZIP T-SQL JOIN yapmak için daha fazla standart yol biliyor musunuz?

+8

Yapmanız gereken çözüm benim çözümüm. – Johan

+4

'ZIP JOIN'? O nedir? –

+4

@ypercube http://stackoverflow.com/a/17581681/2042090 –

cevap

0

Sen the CTE kurtulmak alabilir veya query shorter

bu

select Id,Color,Value from 
(
    SELECT [Id], [Color], ROW_NUMBER() OVER (ORDER BY [Id]) AS 'No' 
    FROM #Foo 
)x full outer join 
(
    SELECT [Value], ROW_NUMBER() OVER (ORDER BY [Value]) AS 'No' 
    FROM #Bar 
)y 
on x.No=y.No 
+3

"Daha iyi optimize edilmiş" çünkü birleştirme türünü değiştirdiniz. CTE'ler, her zaman yaptığınız gibi, sorgu iyileştirici tarafından belirtilir. – usr

+4

Onlar "FEF" değil, "SOL" a katılmalılar. –

+0

oopss !! evet ikisi de aynı! belki bu daha kısa? –

0

gibi alt sorgu yıllardan bu yeterli Will yapmak alabilirim?

SELECT 
    F.ID AS ID, 
    F.Color AS Color, 
    B.Value AS Value 
FROM #Foo F 
    LEFT OUTER JOIN #Bar B ON F.ID = FLOOR(B.Value) 

--this DOES seem to return the correct output, but I'm not sure that my logic 
--is what you are after 
SELECT 
    F.ID AS ID, 
    F.Color AS Color, 
    B.Value AS Value 
FROM 
    (
     VALUES 
     (1,'Red'),(2,'Green'),(3,'Blue'),(4, NULL) 
    ) AS F(ID, Color) 
    LEFT OUTER JOIN 
    (
     VALUES  
     (1), (2.5) 
    ) AS B(Value) 
    ON F.ID = FLOOR(B.Value) 

(Kuşkusuz, ben bayan-yorumlama soru olabilir) Yoksa aslında isteyen vardır:

  • Sıralama #Foo kimliği
  • sırala #Boo Değer
  • Maç tarafından:
    • #bar dan "İlk" satırla #Foo dan "İlk" satır
    • # gelen "İkinci" satırla #Foo gelen "İkinci" satırını (Üzgünüm, ama bir "Posta JOIN" Ne aşina değilim

vb

  • ... olduğunu Bar. @RszardDzegan tarafından sağlanan bağlantıya bakacağım.)

  • +0

    İhtiyacım olan şey, değerlerinden bağımsız olarak iki tabloyu birbirine yapıştırmak. Varsayalım ki, iki sonuç kümesine sahipler ve aşağıdaki gibi bir arada ayarlayarak bir, tekdüze tablo oluşturmak isterler: B ilk satır A ilk sıranın yanında B ikinci satır A ikinci satırın yanındaki vb. Değerler böyle bir senaryoda önemsizdir. Sadece SQL'de kolay bir çözüm arıyorum. –

    +0

    Bu durumda, CTE'lerle olan çözümünüzün muhtemelen en iyi bahistirsiniz, sadece performansa dikkat edin. CTE'lerin BÜYÜK bir hayranıyım ve nedenlerini bulabileceğim her yerde kullanıyorum, ANCAK CTE sonuç kümeleri büyük miktarda veri döndürdüğünde performans sorunları yaşadım. "Büyük" genellikle yüz MB'lar anlamına gelir. Diğer bir endişe, "set" veri ile uğraşırken, EXACTLY "first row" ve "second row", vs ... ne anlama geliyor? Varsa, satırların mantıksal olarak sıralayabileceği SOME sütunu varsayarsak, ek bir nokta "bağlar" ile ne yapılacağıdır. FANTASTİK SORU !! –

    -1

    Bu durumda satır numaraları verildiğinden #Foo için yeni satır numaraları oluşturmayı atlayabilirsiniz.

    Sonra çözelti Bu çözüm test edilmiş ve kanıtlanmıştır

    SELECT F.Id,F.Color,newBar.Value from #Foo as F 
    LEFT JOIN 
    (
        SELECT [Value], ROW_NUMBER() OVER (ORDER BY [Value]) AS 'No' 
        FROM #Bar 
    ) newBar 
    on F.Id=newBar.No 
    

    haline gelecektir. Size #Foo bütün değerlerini verir ve #bar her sıralama yapıldığını değeri için eğer varsa.

    +0

    Bu özel durumda, [Id] sütununun bir satır numarası olarak davrandığını kabul ediyorum, ancak bu bir pruva değil. Genel bir çözüm arıyorum. –

    0

    böyle bir şey deneyebilirsiniz:

    DECLARE @Foo TABLE (Id INT, Color VARCHAR(10)); 
    DECLARE @Bar TABLE (Value DECIMAL(2, 1)) 
    
    INSERT INTO @Foo (Id, Color) 
    VALUES (1, 'Red'), (2, 'Green'), (3, 'Blue'), (4, NULL) 
    
    INSERT INTO @Bar (Value) 
    VALUES (1), (2.5); 
    
    WITH ECROSS 
    AS (
        SELECT F.Id, F.Color, B.Value, DENSE_RANK() OVER (
          ORDER BY F.Id 
          ) AS No1, DENSE_RANK() OVER (
          ORDER BY B.Value 
          ) AS No2 
        FROM @Foo F, @Bar B 
        ) 
    SELECT A.id, A.Color, B.Value 
    FROM ECROSS A 
    LEFT JOIN ECROSS B ON A.No1 = B.No2 
        AND A.No1 = B.No1 
    GROUP BY A.id, A.Color, B.Value 
    
    0
    DECLARE @Foo TABLE (pk_id int identity(1,1), Id INT, Color VARCHAR(10)); 
    DECLARE @Bar TABLE (pk_id int identity(1,1), Value DECIMAL(2, 1)) 
    
    INSERT INTO @Foo (Id, Color) 
    VALUES (1, 'Red'), (2, 'Green'), (3, 'Blue'), (4, NULL) 
    
    INSERT INTO @Bar (Value) 
    VALUES (1), (2.5); 
    
    SELECT F.id, F.Color, B.Value 
    FROM @Foo F 
        LEFT JOIN @Bar B ON F.pk_id = B.pk_id 
    
    0

    Aşağıdaki kodu deneyin. Sadece grup başına bir satır numarası ile aynı yapıda hem veri türlerini sağlamanız gerekir. Bunun üzerine beklenen sonuç üretmek için MİL operatörünü kullanabilirsiniz.

    WITH 
    CTE_FOO AS 
    (
        SELECT 
         [Group] 
         ,[Spread] 
         ,[Aggregate] 
        FROM 
         (VALUES 
          (1, 1, N'Red' ) 
         ,(2, 1, N'Green') 
         ,(3, 1, N'Blue') 
         ,(4, 1, NULL ) 
        ) AS FOO([Group], [Spread], [Aggregate]) 
    ), 
    CTE_BAR AS 
    (
        SELECT 
         [Group] 
         ,[Spread] 
         ,CAST([Aggregate] AS nvarchar(max)) AS [Aggregate] 
        FROM 
         (VALUES 
          (1, 2, 1 ) 
         ,(2, 2, 2.5) 
        ) AS BAR([Group], [Spread], [Aggregate]) 
    ), 
    CTE_FOOBAR AS 
    (
        SELECT [Group], [Spread], [Aggregate] FROM CTE_FOO 
        UNION ALL 
        SELECT [Group], [Spread], [Aggregate] FROM CTE_BAR 
    ) 
    SELECT 
        [Group] AS [ID] 
        ,[1]  AS [Color] 
        ,[2]  AS [Value] 
    FROM 
        CTE_FOOBAR 
    PIVOT 
        (
         MAX([Aggregate]) FOR [Spread] IN ([1], [2]) 
        ) AS PivotTable 
    
    1

    Bunu basitçe deneyebilirsiniz.

    ;WITH CTE AS 
    (
        SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS Id, Value FROM #Bar 
    ) 
    SELECT F.Id, F.Color, CTE.Value 
    FROM #Foo F 
    LEFT JOIN CTE ON CTE.Id = F.Id 
    
    İlgili konular