Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Alt sorgu, sorgu dili içindeki başka bir sorgunun içinde iç içe yerleştirilmiş bir sorgudur. Alt sorgu, iç sorgu veya iç SELECTolarak da adlandırılır. Alt sorgu içeren deyim genellikle dış sorgu olarak adlandırılır.
Alt sorgu türleri
İki ana alt sorgu türü vardır:
- Bağıntılı: Dış sorgudaki değerlere başvuran bir alt sorgu. Alt sorgu, dış sorgunun işlediği her satır için bir kez değerlendirilir.
- Bağıntısız: Dış sorgudan bağımsız bir alt sorgu. Dış sorguya bağlı kalmadan kendi başına çalıştırılabilir.
Alt sorgular, döndürdikleri satır ve sütun sayısına göre daha fazla sınıflandırılabilir. Üç tür kur vardır:
- Tablo: Birden çok satır ve birden çok sütun döndürür.
- Çoklu değer: Birden çok satır ve tek bir sütun döndürür.
- Skaler: Tek bir satır ve tek bir sütun döndürür.
Sorgu dilindeki sorgular her zaman tek bir sütun döndürür (basit bir değer veya karmaşık bir öğe). Bu nedenle, yalnızca çok değerli ve skaler alt sorgular uygulanabilir. Çok değerli alt sorguyu yalnızca yan tümcesinde FROM ilişkisel ifade olarak kullanabilirsiniz. Skaler alt sorguyu or WHERE yan tümcesinde SELECT skaler ifade olarak veya yan tümcesinde FROM ilişkisel ifade olarak kullanabilirsiniz.
Çok değerli alt sorgular
Çok değerli alt sorgular bir öğe kümesi döndürür ve her zaman yan tümcesinde FROM kullanılır. Bunlar şu amaçla kullanılır:
- İfadeleri iyileştirme
JOIN(kendi kendine birleştirme). - Pahalı ifadeleri bir kez değerlendirme ve birden çok kez başvurma.
Kendi kendine birleştirme ifadelerini iyileştirme
Çok değerli alt sorgular, yan tümcedeki WHERE tüm çapraz birleşimlerden sonra değil, her select-many ifadesinden sonra koşul göndererek ifadeleri iyileştirebilirJOIN.
Aşağıdaki sorguyu göz önünde bulundurun:
SELECT VALUE
COUNT(1)
FROM
products p
JOIN
t in p.tags
JOIN
s in p.sizes
JOIN
c in p.colors
WHERE
t.key IN ("fabric", "material") AND
s["order"] >= 3 AND
c LIKE "%gray%"
Bu sorgu için dizin, *üçten büyük bir keymaterialfabric değere sahip en az bir boyuta ve alt dize olarak en az bir order renge sahip etiketi olan herhangi bir öğeyle gray eşleşir. Buradaki JOIN ifade, herhangi bir filtre uygulanmadan önce eşleşen her öğe için , ve colors dizilerinin tüm öğelerinin tagssizesçarpımını gerçekleştirir.
Yan WHERE tümcesi daha sonra her $<c, t, n, s>$ tanımlama grubuna filtre koşulunu uygular. Örneğin, eşleşen bir öğenin üç dizinin her birinde on öğe varsa, şu formülü kullanarak 1.000 tanımlama grubuna genişletir:
$$1 x 10 x 10 x 10$$
Burada alt sorgular kullanmak, sonraki ifadeyle birleştirmeden önce birleştirilmiş dizi öğelerini filtrelemeye yardımcı olabilir.
Bu sorgu, önceki sorguya eşdeğerdir ancak alt sorgular kullanır:
SELECT VALUE
COUNT(1)
FROM
products p
JOIN
(SELECT VALUE t FROM t IN p.tags WHERE t.key IN ("fabric", "material"))
JOIN
(SELECT VALUE s FROM s IN p.sizes WHERE s["order"] >= 3)
JOIN
(SELECT VALUE c FROM c in p.colors WHERE c LIKE "%gray%")
Etiketler dizisindeki yalnızca bir öğenin filtreyle eşleşdiğini ve hem miktar hem de hisse senedi dizileri için beş öğe olduğunu varsayalım. İfade JOIN daha sonra ilk sorgudaki 1.000 öğe yerine bu formülü kullanarak 25 tanımlama grubuna genişletilir:
$$1 x 1 x 5 x 5$$
Bir kez değerlendirme ve birçok kez başvurma
Alt sorgular, kullanıcı tanımlı işlevler (UDF'ler), karmaşık dizeler veya aritmetik ifadeler gibi pahalı ifadelerle sorguları iyileştirmeye yardımcı olabilir. bir alt sorguyu ifadeyle birlikte kullanarak ifadeyi bir JOIN kez değerlendirebilir ancak birçok kez başvurabilirsiniz.
Bu örnek sorgu, fiyatı sorguda 25% kat ekiyle hesaplar.
SELECT VALUE {
subtotal: p.price,
total: (p.price * 1.25)
}
FROM
products p
WHERE
(p.price * 1.25) < 22.25
Hesaplamayı yalnızca bir kez çalıştıran eşdeğer bir sorgu aşağıdadır:
SELECT VALUE {
subtotal: p.price,
total: totalPrice
}
FROM
products p
JOIN
(SELECT VALUE p.price * 1.25) totalPrice
WHERE
totalPrice < 22.25
[
{
"subtotal": 15,
"total": 18.75
},
{
"subtotal": 10,
"total": 12.5
},
...
]
İpucu
İfadelerin ürün arası davranışını JOIN göz önünde bulundurun. İfade olarak değerlendirebiliyorsa undefined, ifadenin JOIN doğrudan değer yerine alt sorgudan bir nesne döndürerek her zaman tek bir satır ürettiğinden emin olmanız gerekir.
Dış başvuru verileriyle ilişkisel birleşimi taklit edin
Genellikle ölçü birimleri gibi nadiren değişen statik verilere başvurmanız gerekebilir. Bir sorgudaki her öğe için statik verileri yinelememek idealdir. Bu yinelemeyi önlemek, tek tek öğe boyutunu daha küçük tutarak depolamadan tasarruf sağlar ve yazma performansını artırır. Statik başvuru verileri koleksiyonuyla iç birleşim semantiğini taklit etmek için bir alt sorgu kullanabilirsiniz.
Örneğin, bir giysinin uzunluğunu temsil eden bu ölçü kümesini göz önünde bulundurun:
| Boyut | Length | Units |
|---|---|---|
xs |
63.5 |
cm |
s |
64.5 |
cm |
m |
66.0 |
cm |
l |
67.5 |
cm |
xl |
69.0 |
cm |
xxl |
70.5 |
cm |
Aşağıdaki sorgu, çıktıya birimin adını eklemeniz için bu verilerle birleştirmeyi taklit eder:
SELECT
p.name,
p.subCategory,
s.description AS size,
m.length,
m.unit
FROM
products p
JOIN
s IN p.sizes
JOIN m IN (
SELECT VALUE [
{size: 'xs', length: 63.5, unit: 'cm'},
{size: 's', length: 64.5, unit: 'cm'},
{size: 'm', length: 66, unit: 'cm'},
{size: 'l', length: 67.5, unit: 'cm'},
{size: 'xl', length: 69, unit: 'cm'},
{size: 'xxl', length: 70.5, unit: 'cm'}
]
)
WHERE
s.key = m.size
Skaler alt sorgular
Skaler alt sorgu ifadesi, tek bir değer olarak değerlendirilen bir alt sorgudur. Skaler alt sorgu ifadesinin değeri, alt sorgunun projeksiyonunun (SELECT yan tümcesi) değeridir. Skaler ifadenin geçerli olduğu birçok yerde skaler alt sorgu ifadesi kullanabilirsiniz. Örneğin, hem ve SELECTWHERE yan tümcelerindeki herhangi bir ifadede skaler alt sorgu kullanabilirsiniz.
Skaler alt sorgu kullanmak her zaman sorgunuzu iyileştirmeye yardımcı olmaz. Örneğin, skaler alt sorguların bir sisteme veya kullanıcı tanımlı işlevlere bağımsız değişken olarak geçirilmesi, kaynak birimi (RU) tüketimini veya gecikme süresini azaltmada hiçbir fayda sağlamaz.
Skaler alt sorgular şu şekilde sınıflandırılabilir:
- Basit ifade skaler alt sorguları
- Skaler alt sorguları toplama
Basit ifade skaler alt sorguları
Basit ifade skaler alt sorgusu, herhangi bir toplama ifadesi içermeyen yan tümcesine sahip bağıntılı bir SELECT alt sorgudur. Derleyici bunları daha büyük bir basit ifadeye dönüştürdüğünden bu alt sorgular iyileştirme avantajı sağlamaz. İç ve dış sorgular arasında bağıntılı bağlam yoktur.
İlk örnek olarak, bu önemsiz sorguyu göz önünde bulundurun.
SELECT
1 AS a,
2 AS b
Basit ifadeli skaler alt sorgu kullanarak bu sorguyu yeniden yazabilirsiniz.
SELECT
(SELECT VALUE 1) AS a,
(SELECT VALUE 2) AS b
Her iki sorgu da aynı çıkışı üretir.
[
{
"a": 1,
"b": 2
}
]
Bu sonraki örnek sorgu, benzersiz tanımlayıcıyı basit ifade skaler alt sorgu olarak bir önek ile birleştirir.
SELECT
(SELECT VALUE CONCAT('ID-', p.id)) AS internalId
FROM
products p
Bu örnek, her öğe için yalnızca ilgili alanları döndürmek için basit ifade skaler alt sorgu kullanır. Sorgu her öğe için bir çıkış oluşturur, ancak yalnızca alt sorgudaki filtreyi karşılıyorsa yansıtılan alanı içerir.
SELECT
p.id,
(SELECT p.name WHERE CONTAINS(p.name, "Shoes")).name
FROM
products p
[
{
"id": "00000000-0000-0000-0000-000000004041",
"name": "Remdriel Shoes"
},
{
"id": "00000000-0000-0000-0000-000000004322"
},
{
"id": "00000000-0000-0000-0000-000000004055"
}
]
Skaler alt sorguları toplama
Toplam skaler alt sorgu, projeksiyonunda veya filtresinde tek bir değere göre değerlendirilen bir toplama işlevine sahip olan bir alt sorgudur.
İlk örnek olarak, aşağıdaki alanlara sahip bir öğeyi göz önünde bulundurun.
[
{
"name": "Blators Snowboard Boots",
"colors": [
"turquoise",
"cobalt",
"jam",
"galliano",
"violet"
],
"sizes": [ ... ],
"tags": [ ... ]
}
]
Aşağıda projeksiyonunda tek bir toplama işlevi ifadesi bulunan bir alt sorgu verilmiştir. Bu sorgu, her öğe için tüm etiketleri sayar.
SELECT
p.name,
(SELECT VALUE COUNT(1) FROM c IN p.colors) AS colorsCount
FROM
products p
WHERE
p.id = "00000000-0000-0000-0000-000000004389"
[
{
"name": "Blators Snowboard Boots",
"colorsCount": 5
}
]
Filtre içeren aynı alt sorgu aşağıda verilmiştır.
SELECT
p.name,
(SELECT VALUE COUNT(1) FROM c IN p.colors) AS colorsCount,
(SELECT VALUE COUNT(1) FROM c IN p.colors WHERE c LIKE "%t") AS colorsEndsWithTCount
FROM
products p
[
{
"name": "Blators Snowboard Boots",
"colorsCount": 5,
"colorsEndsWithTCount": 2
}
]
Birden çok toplama işlevi ifadesi içeren başka bir alt sorgu aşağıda verilmiştir:
SELECT
p.name,
(SELECT VALUE COUNT(1) FROM c IN p.colors) AS colorsCount,
(SELECT VALUE COUNT(1) FROM s in p.sizes) AS sizesCount,
(SELECT VALUE COUNT(1) FROM t IN p.tags) AS tagsCount
FROM
products p
[
{
"name": "Blators Snowboard Boots",
"colorsCount": 5,
"sizesCount": 7,
"tagsCount": 2
}
]
Son olarak, hem projeksiyonda hem de filtrede toplama alt sorgusunu içeren bir sorgu aşağıda verilmişti:
SELECT
p.name,
(SELECT VALUE COUNT(1) FROM s in p.sizes WHERE s.description LIKE "%Small") AS smallSizesCount,
(SELECT VALUE COUNT(1) FROM s in p.sizes WHERE s.description LIKE "%Large") AS largeSizesCount
FROM
products p
WHERE
(SELECT VALUE COUNT(1) FROM c IN p.colors) >= 5
Bu sorguyu yazmanın daha uygun bir yolu, alt sorguya katılmak ve hem SELECT hem de WHERE yan tümcelerinde alt sorgu diğer adına başvurmaktır. Alt sorguyu hem yansıtma hem de filtrede değil yalnızca join deyimi içinde yürütmeniz gerektiğinden bu sorgu daha verimlidir.
SELECT
p.name,
colorCount,
smallSizesCount,
largeSizesCount
FROM
products p
JOIN
(SELECT VALUE COUNT(1) FROM c IN p.colors) AS colorCount
JOIN
(SELECT VALUE COUNT(1) FROM s in p.sizes WHERE s.description LIKE "%Small") AS smallSizesCount
JOIN
(SELECT VALUE COUNT(1) FROM s in p.sizes WHERE s.description LIKE "%Large") AS largeSizesCount
WHERE
colorCount >= 5 AND
largeSizesCount > 0 AND
smallSizesCount > 0
EXISTS ifadesi
Sorgu dili ifadeleri destekler EXISTS . Bu ifade, sorgu dilinde yerleşik olarak bulunan bir toplam skaler alt sorgudur.
EXISTS bir alt sorgu ifadesi alır ve alt sorgu herhangi bir satır döndürürse döndürür true . Aksi takdirde, o false'ı döndürür.
Sorgu altyapısı boole ifadeleri ile diğer skaler ifadeler arasında ayrım yapmadığından, hem WHERE hem de SELECT yan tümcelerinde kullanabilirsinizEXISTS. Bu davranış, boole ifadesinin yalnızca filtrelerle kısıtlandığı T-SQL'in aksinedir.
EXISTS Alt sorgu olan tek bir değer undefinedEXISTS döndürürse false olarak değerlendirilir. Örneğin, hiçbir şey döndürmeden aşağıdaki sorguyu göz önünde bulundurun.
SELECT VALUE
undefined
İfadeyi EXISTS ve önceki sorguyu bir alt sorgu olarak kullanırsanız, ifade döndürür false.
SELECT VALUE
EXISTS (SELECT VALUE undefined)
[
false
]
Önceki alt sorgudaki VALUE anahtar sözcüğü atlanırsa, alt sorgu tek bir boş nesne içeren bir dizi olarak değerlendirilir.
SELECT
undefined
[
{}
]
Bu noktada, EXISTS nesne ({}) teknik olarak çıktığı için true ifade olarak değerlendirilir.
SELECT VALUE
EXISTS (SELECT undefined)
[
true
]
yaygın kullanım örneğinden ARRAY_CONTAINS biri, bir öğeyi dizideki bir öğenin varlığına göre filtrelemektir. Bu durumda dizinin "dış giyim" adlı bir öğe içerip içermediğini tags kontrol ediyoruz.
SELECT
p.name,
p.colors
FROM
products p
WHERE
ARRAY_CONTAINS(p.colors, "cobalt")
Aynı sorgu alternatif bir seçenek olarak kullanılabilir EXISTS .
SELECT
p.name,
p.colors
FROM
products p
WHERE
EXISTS (SELECT VALUE c FROM c IN p.colors WHERE c = "cobalt")
Ayrıca, ARRAY_CONTAINS yalnızca bir değerin dizi içindeki herhangi bir öğeye eşit olup olmadığını denetleyebilirsiniz. Dizi özelliklerinde daha karmaşık filtrelere ihtiyacınız varsa, bunun yerine kullanın JOIN .
Her birinde dizi içeren accessories birden çok öğe içeren bir kümedeki bu örnek öğeyi göz önünde bulundurun.
[
{
"name": "Cosmoxy Pack",
"tags": [
{
"key": "fabric",
"value": "leather",
"description": "Leather"
},
{
"key": "volume",
"value": "68-gal",
"description": "6.8 Gal"
}
]
}
]
Şimdi, her öğedeki dizideki ve quantityOnHand özelliklerine type göre filtreleyen aşağıdaki sorguyu göz önünde bulundurun.
SELECT
p.name,
t.description AS tag
FROM
products p
JOIN
t in p.tags
WHERE
t.key = "fabric" AND
t["value"] = "leather"
[
{
"name": "Cosmoxy Pack",
"tag": "Leather"
}
]
Koleksiyondaki öğelerin her biri için, dizi öğeleriyle bir çapraz ürün gerçekleştirilir. Bu JOIN işlem, dizi içindeki özelliklere göre filtrelemeyi mümkün kılar. Ancak, bu sorguyu RU tüketimi önemlidir. Örneğin, 1.000 öğenin her dizide 100 öğesi varsa, şu formülü kullanarak 100.000 tanımlama grubuna genişletir:
$1.000 x 100$$
Kullanmak EXISTS , bu pahalı çapraz üründen kaçınmaya yardımcı olur. Bu sonraki örnekte sorgu, alt sorgu içindeki dizi öğelerine EXISTS filtre ekler. Bir dizi öğesi filtreyle eşleşiyorsa, bunu yansıtıp EXISTS true olarak değerlendirirsiniz.
SELECT VALUE
p.name
FROM
products p
WHERE
EXISTS (
SELECT VALUE
t
FROM
t IN p.tags
WHERE
t.key = "fabric" AND
t["value"] = "leather"
)
[
"Cosmoxy Pack"
]
Sorguların projeksiyonda diğer ad EXISTS kullanmasına ve diğer adlara başvurmasına da izin verilir:
SELECT
p.name,
EXISTS (
SELECT VALUE
t
FROM
t IN p.tags
WHERE
t.key = "fabric" AND
t["value"] = "leather"
) AS containsFabricLeatherTag
FROM
products p
[
{
"name": "Cosmoxy Pack",
"containsFabricLeatherTag": true
}
]
ARRAY ifadesi
Sorgunun sonuçlarını dizi olarak yansıtmak için ifadeyi ARRAY kullanabilirsiniz. Bu ifadeyi yalnızca sorgunun SELECT yan tümcesinde kullanabilirsiniz.
Bu örnekler için en azından bu öğeye sahip bir kapsayıcı olduğunu varsayalım.
[
{
"name": "Menti Sandals",
"sizes": [
{
"key": "5"
},
{
"key": "6"
},
{
"key": "7"
},
{
"key": "8"
},
{
"key": "9"
}
]
}
]
Bu ilk örnekte ifade yan tümcesi SELECT içinde kullanılır.
SELECT
p.name,
ARRAY (
SELECT VALUE
s.key
FROM
s IN p.sizes
) AS sizes
FROM
products p
WHERE
p.name = "Menti Sandals"
[
{
"name": "Menti Sandals",
"sizes": [
"5",
"6",
"7",
"8",
"9"
]
}
]
Diğer alt sorgularda olduğu gibi, ifadeye ARRAY sahip filtreler de mümkündür.
SELECT
p.name,
ARRAY (
SELECT VALUE
s.key
FROM
s IN p.sizes
WHERE
STRINGTONUMBER(s.key) <= 6
) AS smallSizes,
ARRAY (
SELECT VALUE
s.key
FROM
s IN p.sizes
WHERE
STRINGTONUMBER(s.key) >= 9
) AS largeSizes
FROM
products p
WHERE
p.name = "Menti Sandals"
[
{
"name": "Menti Sandals",
"smallSizes": [
"5",
"6"
],
"largeSizes": [
"9"
]
}
]
Dizi ifadeleri, alt sorgulardaki yan tümceden FROM sonra da gelebilir.
SELECT
p.name,
z.s.key AS sizes
FROM
products p
JOIN
z IN (
SELECT VALUE
ARRAY (
SELECT
s
FROM
s IN p.sizes
WHERE
STRINGTONUMBER(s.key) <= 8
)
)
[
{
"name": "Menti Sandals",
"sizes": "5"
},
{
"name": "Menti Sandals",
"sizes": "6"
},
{
"name": "Menti Sandals",
"sizes": "7"
},
{
"name": "Menti Sandals",
"sizes": "8"
}
]