2016-03-29 13 views
0

Aşağıdaki sorguya sahibim. Girdi olarak productid (2,4,5) verildiğinde keyid ile bu listeyi ilişkilendirmek istiyorum. Sonra o anahtarlıklar ile ilişkili tüm ürünleri almak istiyorum.Sadece tek bir sql sorgusu ile CTE ve SELECT'in değiştirilmesi mümkün mü? (Bağımlı sonuçlar)

Örneğin: ürünüm, spiro'ya girdi olarak 2,4,5 olarak geçtiğimi varsayalım, anahtarlıkları 22,34,35,38 (CTE sonucu) olarak alacağım. Bu tuşlar giriş ürün listesine eşlenir. Bu tuşlara bağlı olarak (CTE sonucu) bu tuşlarla ilişkili tüm ürünleri istiyorum. Keyid = 22 ürün kimliğine sahip ürün adlarının şu anda 2,4,5,89 & keyid = 34 ürün isimleri olduğunu şimdi 2,4,5,23,45 vb. Ürünlere sahip olacak.

Yukarıdaki problem için aşağıdaki çözüm. Sadece bu çözümü geliştirip geliştiremeyeceğimizi mi yoksa iki masa tekrarlanırken bu işi tek bir sorguda yapıp yapamayacağımı umuyorum.

ürün ve productkeymapping tablolar için
WITH GetKey_CTE 
AS 
(
    SELECT k.id, some other select statements 
    FROM KeyDim k 
     INNER JOIN KeyData kd on kd.id = k.id 
     INNER JOIN KeyProductMapping kpm on kpm.id = k.id and kpm.mkey = k.mkey 
     INNER JOIN Products p on p.productid = kpm.productid 
         and p.productid IN (2,4,5) 
     LEFT JOIN some more joins 
    WHERE clause conditions 
) 

SELECT cte.id as keyid, pn.productname, some other columns 
FROM GetKey_CTE cte 
INNER JOIN KeyProductMapping kpm on cte.id = kpm.id 
INNER JOIN Products pn on pn.productid = kpm.productid 
ORDER BY cte.id 

Veri kümesi Örnek: Ürünler tablo için

:

productid name 
1   car 
2   bike 
3   plane 
4   bus 
5   train 
45  cycle 

ProductKeyMapping Tablo

productid keyid 
1    23 
2    987 
45   23 
1    56 

giriş productid 1 demek, daha sonra, son sonucu olmalıdır :

keyid productid name 
23  1   car 
23  45   cycle 
56  1   car 
+0

, biz eğer söyleyemem 'KeyProductsMapping' ve' Products' tablolarına iki atıfta bulunmaktan kaçınmak mümkündür. (Ortak bir tablo ifadesi kesinlikle gerekli değildir. Aynı sorgu, satır içi görünüm olarak görünebilir ve cte (veya satır içi görünüm) sorgularının GROUP BY içermediği göz önüne alındığında, büyük olasılıkla bunun gerekmeyeceği düşünülür. Ayrı bir SELECT Sorgu tek bir SELECT ile yeniden yazılabilir, ancak bu sorgu aynı tablo referanslarına sahip olacaktı ... 'Ürünler' ve 'KeyProductsMapping 'tablolarına iki referans. – spencer7593

+0

Benim için hiçbir anlam ifade etmiyor: INNER JOIN Ürünler pn on cte.productid = kpm.productid – Paparazzi

+0

mymistake, ben ilişkiyi tablo – user2406618

cevap

0

ayrıca aşağıdaki gibi bir satır içi görünümü ile CTE yerini ama yine KATILDI çoğaltarak neden emin not edebilirsiniz alt sorgu

SELECT * FROM KeyProductMapping km 
INNER JOIN 
(
SELECT k.id, some other select statements 
    FROM KeyDim k 
     INNER JOIN KeyData kd ON kd.id = k.id 
     INNER JOIN KeyProductMapping kpm ON kpm.id = k.id AND kpm.mkey = k.mkey 
     INNER JOIN Products p ON p.productid = kpm.productid 
         AND p.productid IN (2,4,5) 
     LEFT JOIN some more joins 
    WHERE clause conditions) AS p ON p.id = km.id 
INNER JOIN Products pn ON p.productid = km.productid 
ORDER BY cte.id 
0

kullanılarak yapılır yapabilirsiniz. Daha fazla bakmak için istediğiniz örnekle birlikte bazı örnek verileri gönderir misiniz? Eğer doğrultusunda CTE ile sorgulamak sana Üstü

SELECT cte.id AS keyid, pn.productname, some other columns 
FROM (
    SELECT k.id, some other select statements 
    FROM KeyDim k 
     INNER JOIN KeyData kd ON kd.id = k.id 
     INNER JOIN KeyProductMapping kpm ON kpm.id = k.id AND kpm.mkey = k.mkey 
     INNER JOIN Products p ON p.productid = kpm.productid 
         AND p.productid IN (2,4,5) 
     LEFT JOIN some more joins 
    WHERE clause conditions) cte 
INNER JOIN KeyProductMapping kpm ON cte.id = kpm.id 
INNER JOIN Products pn ON cte.productid = kpm.productid 
ORDER BY cte.id 
0
SELECT cte.id as keyid, pn.productname, some other columns 
FROM (SELECT k.id, some other select statements 
     FROM KeyDim k 
     JOIN KeyData kd 
       on kd.id = k.id 
     JOIN KeyProductMapping kpm 
       on kpm.id = k.id 
       and kpm.mkey = k.mkey 
     JOIN Products p 
       on p.productid = kpm.productid 
       and p.productid IN (2,4,5) 
     LEFT JOIN some more joins 
     WHERE clause conditions 
    ) CTE 
    JOIN KeyProductMapping kpm 
     on cte.id = kpm.id 
    JOIN Products pn 
     on pn.productid = kpm.productid 
ORDER BY cte.id 

Bir sürü benim

JOIN KeyProductMapping kpm 
     on kpm.id = k.id 
     and kpm.mkey = k.mkey 
JOIN Products p 
     on p.productid = kpm.productid 
     and p.productid IN (2,4,5) 

için mantıklı değil

(a alt sorgu)

aynıdır Ürünün bu değerleri olmadığı sürece
JOIN KeyProductMapping kpm 
     on kpm.id = k.id 
     and kpm.mkey = k.mkey 
     and p.productid IN (2,4,5) 

es neden

SELECT kd.id -- move this to main select, some other select statements 
FROM KeyData kd 

neden

olarak

SELECT k.id, some other select statements 
    FROM KeyDim k 
    JOIN KeyData kd 
     on kd.id = k.id 

aynı?

LEFT JOIN some more joins 

ana açıklamaya

+0

Hi Paparazzi ile ilişkisi var, diğer birleşmeler de bazı '' daha fazla katılma '' sebebi budur. kpm.mkey = k.mkey hakkında, bu bölümü atlayabilirsiniz, aslında bahsetmediğim birleşmelerde bir tane daha masa var, bu yüzden anahtar tablası -> keyfact -> productkeymap -> product zincir y ana odaklama, birleştirme kombinasyonlarını azaltmak için tüm tabloyu yalnızca bir kez kullanmaktır. – user2406618

+0

ancak ana sorguda ihtiyacınız olan diğer değerleri al – Paparazzi

+0

evet aslında cte değerleri kullanıyordum, ana sorguda cte.col1, cte.col2 deyin. keydim tablosu pek çok birleşim ile ilişkilidir, bu yüzden onu cte olarak sakladım. ama yine de bu birleşmeleri ana sorguya taşıyabilir ve bu birleşimleri cte ile birleştirebilirim. Bu noktaya katılıyorum. – user2406618

1

sadece verilere bakarak bu hareketin ve şema (varlıklar ve ilişkiler) daha iyi anlamak olmadan bu kadar basit örnek

select pm2.*, product.name 
    from productmapping pm1 
    join productmapping pm2 
     on pm2.keyid = pm1.keyid 
     and pm1.productid in (1) 
    join product 
     on product.id = pm2.productid 


declare @product table(id int, name varchar(20)); 
declare @map table(productid int, keyid int); 
insert into @product values 
(1, 'car'), 
(2, 'bike'), 
(3, 'plane'), 
(4, 'bus'), 
(5, 'train'), 
(45, 'cycle'); 
insert into @map values 
(1, '23'), 
(2, '987'), 
(45, '23'), 
(1, '56'); 
select pm2.*, p.name 
    from @map pm1 
    join @map pm2 
     on pm2.keyid = pm1.keyid 
     and pm1.productid in (1) 
    join @product p 
     on p.id = pm2.productid 
order by pm2.keyid; 
+0

kendi kendine çalışmaya çalıştı. Asıl sorgum için sol birleştirmeyi kullandım. Ürün listesi için önce anahtar kelimeyi almak için önce anahtar kimlikleri eşleştirmek için tekrar birleştirme yapın – user2406618

İlgili konular