Sdílet prostřednictvím


Klauzule FROM plus JOIN, APPLY, PIVOT (Transact-SQL)

platí pro: SQL Server 2016 (13.x) a novější verze Azure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)koncový bod analýzy SQL v Microsoft FabricWarehouse v databázi Microsoft FabricSQL v Microsoft Fabric

V jazyce Transact-SQL je klauzule FROM k dispozici v následujících příkazech:

Klauzule FROM se obvykle vyžaduje u příkazu SELECT. Výjimkou je, že nejsou uvedeny žádné sloupce tabulky a jedinými uvedenými položkami jsou literály nebo proměnné nebo aritmetické výrazy.

Tento článek také popisuje následující klíčová slova, která lze použít v klauzuli FROM:

Transact-SQL konvence syntaxe

Syntax

Syntaxe pro SQL Server, Azure SQL Database a databázi SQL Fabric:

[ FROM { <table_source> } [ , ...n ] ]
<table_source> ::=
{
    table_or_view_name [ FOR SYSTEM_TIME <system_time> ] [ [ AS ] table_alias ]
        [ <tablesample_clause> ]
        [ WITH ( < table_hint > [ [ , ] ...n ] ) ]
    | rowset_function [ [ AS ] table_alias ]
        [ ( bulk_column_alias [ , ...n ] ) ]
    | user_defined_function [ [ AS ] table_alias ]
    | OPENXML <openxml_clause>
    | derived_table [ [ AS ] table_alias ] [ ( column_alias [ , ...n ] ) ]
    | <joined_table>
    | <pivoted_table>
    | <unpivoted_table>
    | @variable [ [ AS ] table_alias ]
    | @variable.function_call ( expression [ , ...n ] )
        [ [ AS ] table_alias ] [ (column_alias [ , ...n ] ) ]
}
<tablesample_clause> ::=
    TABLESAMPLE [ SYSTEM ] ( sample_number [ PERCENT | ROWS ] )
        [ REPEATABLE ( repeat_seed ) ]

<joined_table> ::=
{
    <table_source> <join_type> <table_source> ON <search_condition>
    | <table_source> CROSS JOIN <table_source>
    | left_table_source { CROSS | OUTER } APPLY right_table_source
    | [ ( ] <joined_table> [ ) ]
}
<join_type> ::=
    [ { INNER | { { LEFT | RIGHT | FULL } [ OUTER ] } } [ <join_hint> ] ]
    JOIN

<pivoted_table> ::=
    table_source PIVOT <pivot_clause> [ [ AS ] table_alias ]

<pivot_clause> ::=
        ( aggregate_function ( value_column [ [ , ] ...n ] )
        FOR pivot_column
        IN ( <column_list> )
    )

<unpivoted_table> ::=
    table_source UNPIVOT <unpivot_clause> [ [ AS ] table_alias ]

<unpivot_clause> ::=
    ( value_column FOR pivot_column IN ( <column_list> ) )

<column_list> ::=
    column_name [ , ...n ]

<system_time> ::=
{
      AS OF <date_time>
    | FROM <start_date_time> TO <end_date_time>
    | BETWEEN <start_date_time> AND <end_date_time>
    | CONTAINED IN (<start_date_time> , <end_date_time>)
    | ALL
}

    <date_time>::=
        <date_time_literal> | @date_time_variable

    <start_date_time>::=
        <date_time_literal> | @date_time_variable

    <end_date_time>::=
        <date_time_literal> | @date_time_variable

Syntaxe paralelního datového skladu, Azure Synapse Analytics:

FROM { <table_source> [ , ...n ] }

<table_source> ::=
{
    [ database_name . [ schema_name ] . | schema_name . ] table_or_view_name [ AS ] table_or_view_alias
    [ <tablesample_clause> ]
    | derived_table [ AS ] table_alias [ ( column_alias [ , ...n ] ) ]
    | <joined_table>
}

<tablesample_clause> ::=
    TABLESAMPLE ( sample_number [ PERCENT ] ) -- Azure Synapse Analytics Dedicated SQL pool only

<joined_table> ::=
{
    <table_source> <join_type> <table_source> ON search_condition
    | <table_source> CROSS JOIN <table_source>
    | left_table_source { CROSS | OUTER } APPLY right_table_source
    | [ ( ] <joined_table> [ ) ]
}

<join_type> ::=
    [ INNER ] [ <join hint> ] JOIN
    | LEFT  [ OUTER ] JOIN
    | RIGHT [ OUTER ] JOIN
    | FULL  [ OUTER ] JOIN

<join_hint> ::=
    REDUCE
    | REPLICATE
    | REDISTRIBUTE

Syntaxe pro Microsoft Fabric:

FROM { <table_source> [ , ...n ] }

<table_source> ::=
{
    [ database_name . [ schema_name ] . | schema_name . ] table_or_view_name [ AS ] table_or_view_alias
    | derived_table [ AS ] table_alias [ ( column_alias [ , ...n ] ) ]
    | <joined_table>
}

<joined_table> ::=
{
    <table_source> <join_type> <table_source> ON search_condition
    | <table_source> CROSS JOIN <table_source>
    | left_table_source { CROSS | OUTER } APPLY right_table_source
    | [ ( ] <joined_table> [ ) ]
}

<join_type> ::=
    [ INNER ] [ <join hint> ] JOIN
    | LEFT  [ OUTER ] JOIN
    | RIGHT [ OUTER ] JOIN
    | FULL  [ OUTER ] JOIN

<join_hint> ::=
    REDUCE
    | REPLICATE
    | REDISTRIBUTE

Argumenty

<table_source>

Určuje tabulku, zobrazení, proměnnou tabulky nebo odvozený zdroj tabulky s aliasem nebo bez něj, která se má použít v příkazu Transact-SQL. V příkazu lze použít až 256 zdrojů tabulek, i když se limit liší v závislosti na dostupné paměti a složitosti jiných výrazů v dotazu. Jednotlivé dotazy nemusí podporovat až 256 zdrojů tabulek.

Poznámka

Výkon dotazů může mít velké množství tabulek odkazovaných v dotazu. Čas kompilace a optimalizace jsou ovlivněny také dalšími faktory. Patří mezi ně přítomnost indexů a indexovaných zobrazení na jednotlivých <table_source> a velikost <select_list> v příkazu SELECT.

Pořadí zdrojů tabulky po klíčovém slovu FROM nemá vliv na vrácenou sadu výsledků. SQL Server vrátí chyby, když se v klauzuli FROM zobrazí duplicitní názvy.

table_or_view_name

Název tabulky nebo zobrazení.

Pokud tabulka nebo zobrazení existuje v jiné databázi na stejné instanci SQL Serveru, použijte plně kvalifikovaný název ve formuláři databáze.schématu.object_name.

Pokud tabulka nebo zobrazení existuje mimo instanci SYSTÉMU SQL Serverl, použijte ve formuláři linked_serverčtyřdílný název .katalog.schématu.objekt. Další informace naleznete v tématu sp_addlinkedserver (Transact-SQL). Čtyřdílný název vytvořený pomocí funkce OPENDATASOURCE jako serverovou část názvu lze také použít k určení vzdáleného zdroje tabulky. Pokud je zadán OPENDATASOURCE, database_name a schema_name nemusí platit pro všechny zdroje dat a podléhá schopnostem zprostředkovatele OLE DB, který přistupuje ke vzdálenému objektu.

[AS] table_alias

Alias pro table_source, který lze použít pro usnadnění nebo rozlišení tabulky nebo zobrazení v poddotazovém spojení nebo poddotazu. Alias je často zkrácený název tabulky, který slouží k odkazování na konkrétní sloupce tabulek ve spojení. Pokud stejný název sloupce existuje ve spojení ve více než jedné tabulce, SQL Server může vyžadovat, aby byl název sloupce kvalifikovaný názvem tabulky, názvem zobrazení nebo aliasem k rozlišení těchto sloupců. Název tabulky nelze použít, pokud je definován alias.

Pokud se použije odvozená tabulka, sada řádků nebo funkce s hodnotou tabulky nebo klauzule operátoru (například PIVOT nebo UNPIVOT), vrátí se požadovaný table_alias na konci klauzule název přidružené tabulky pro všechny sloupce, včetně seskupování sloupců.

WITH (<table_hint> )

Určuje, že optimalizátor dotazů používá strategii optimalizace nebo uzamčení s touto tabulkou a pro tento příkaz. Další informace naleznete v tématu Nápovědy k tabulce (Transact-SQL).

rowset_function

platí pro: SQL Server a SQL Database.

Určuje jednu z funkcí sady řádků, například OPENROWSET, která vrací objekt, který lze použít místo odkazu na tabulku. Další informace o seznamu funkcí sady řádků naleznete v tématu Funkce sady řádků (Transact-SQL).

Použití funkcí OPENROWSET a OPENQUERY k určení vzdáleného objektu závisí na schopnostech zprostředkovatele OLE DB, který přistupuje k objektu.

bulk_column_alias

platí pro: SQL Server a SQL Database.

Volitelný alias pro nahrazení názvu sloupce v sadě výsledků. Aliasy sloupců jsou povoleny pouze v příkazech SELECT, které používají funkci OPENROWSET s možností BULK. Při použití bulk_column_aliaszadejte alias pro každý sloupec tabulky ve stejném pořadí jako sloupce v souboru.

Poznámka

Tento alias přepíše atribut NAME v elementech COLUMN souboru formátu XML, pokud je k dispozici.

user_defined_function

Určuje funkci s hodnotou tabulky.

<openxml_clause> OPENXML

platí pro: SQL Server a SQL Database.

Poskytuje zobrazení sady řádků v dokumentu XML. Další informace najdete v tématuOPENXML (Transact-SQL).

derived_table

Poddotaz, který načte řádky z databáze. derived_table slouží jako vstup pro vnější dotaz.

derived_table může pomocí funkce konstruktoru hodnot tabulky Transact-SQL zadat více řádků. Například SELECT * FROM (VALUES (1, 2), (3, 4), (5, 6), (7, 8), (9, 10) ) AS MyTable(a, b);. Další informace naleznete v tématu Konstruktor hodnot tabulky (Transact-SQL).

column_alias

Volitelný alias pro nahrazení názvu sloupce v sadě výsledků odvozené tabulky. Zahrňte jeden alias sloupce pro každý sloupec v seznamu výběru a uzavřete úplný seznam aliasů sloupců do závorek.

table_or_view_name FOR SYSTEM_TIME <system_time>

platí pro: SQL Server 2016 (13.x) a novější verze a SQL Database.

Určuje, že konkrétní verze dat se vrátí ze zadané dočasné tabulky a z propojené tabulky historie verzí systému.

Klauzule TABLESAMPLE

platí pro: SQL Server, SQL Database a vyhrazené fondy SQL služby Azure Synapse Analytics

Určuje, že se vrátí ukázka dat z tabulky. Ukázka může být přibližná. Tuto klauzuli lze použít u jakékoli primární nebo spojené tabulky v příkazu SELECT nebo UPDATE. U zobrazení nelze zadat TABLESAMPLE.

Poznámka

Při použití TABLESAMPLE pro databáze, které jsou upgradovány na SQL Server, je úroveň kompatibility databáze nastavena na 110 nebo vyšší, PIVOT není povolen v rekurzivním dotazu CTE (Common Table Expression). Další informace naleznete v tématu ÚROVEŇ kompatibility ALTER DATABASE (Transact-SQL).

SYSTÉM

Metoda vzorkování závislá na implementaci určená standardy ISO. V SQL Serveru je to jediná dostupná metoda vzorkování a ve výchozím nastavení se používá. SYSTEM použije metodu vzorkování založenou na stránce, ve které je pro vzorek vybrána náhodná sada stránek z tabulky a všechny řádky na těchto stránkách se vrátí jako ukázková podmnožina.

sample_number

Přesný nebo přibližný číselný výraz, který představuje procento nebo počet řádků. Při zadání pomocí funkce PERCENT se sample_number implicitně převede na hodnotu float; jinak se převede na bigint. Procento je výchozí hodnota.

PROCENTO

Určuje, že sample_number procento řádků tabulky by se mělo načíst z tabulky. Při zadání funkce PERCENT vrátí SQL Server přibližnou hodnotu zadaného procenta. Pokud je zadaná hodnota PERCENT, musí se výraz sample_number vyhodnotit na hodnotu od 0 do 100.

ŘÁDKY

Určuje, že se načtou přibližně sample_number řádků. Při zadání řádků vrátí SQL Server aproximaci zadaného počtu řádků. Pokud je zadána hodnota ROWS, výraz sample_number musí být vyhodnocen jako celočíselná hodnota větší než nula.

OPAKOVATELNÝ

Označuje, že vybranou ukázku je možné vrátit znovu. Pokud je zadána stejná hodnota repeat_seed, vrátí SQL Server stejnou podmnožinu řádků, pokud nebyly provedeny žádné změny v žádné řádky v tabulce. Pokud zadáte jinou repeat_seed hodnotu, SQL Server pravděpodobně vrátí nějaký jiný vzorek řádků v tabulce. Za změny v tabulce se považují následující akce: vložení, aktualizace, odstranění, opětovné sestavení indexu nebo defragmentace a obnovení databáze nebo připojení.

repeat_seed

Konstantní celočíselné výrazy používané SQL Serverem k vygenerování náhodného čísla. repeat_seed je bigint. Pokud není zadaný repeat_seed, SQL Server náhodně přiřadí hodnotu. U konkrétní repeat_seed hodnoty je výsledek vzorkování vždy stejný, pokud v tabulce nebyly použity žádné změny. Výraz repeat_seed musí být vyhodnocen jako celé číslo větší než nula.

Připojená tabulka

Spojená tabulka je sada výsledků, která je součinem dvou nebo více tabulek. U více spojení použijte závorky ke změně přirozeného pořadí spojení.

Typ spojení

Určuje typ operace spojení.

VNITŘNÍ

Určuje, že se vrátí všechny odpovídající dvojice řádků. Zahodí chybějící řádky z obou tabulek. Pokud není zadán žádný typ spojení, toto je výchozí hodnota.

PLNÁ [ VNĚJŠÍ ]

Určuje, že řádek z levé nebo pravé tabulky, která nesplňuje podmínku spojení, je součástí sady výsledků a výstupní sloupce, které odpovídají druhé tabulce, jsou nastaveny na hodnotu NULL. To je navíc ke všem řádkům, které obvykle vrací funkce INNER JOIN.

LEFT [ VNĚJŠÍ ]

Určuje, že všechny řádky z levé tabulky, které nesplňují podmínku spojení, jsou zahrnuty do sady výsledků a výstupní sloupce z druhé tabulky jsou kromě všech řádků vrácených vnitřním spojením nastaveny na hodnotu NULL.

RIGHT [ VNĚJŠÍ ]

Určuje všechny řádky z pravé tabulky, které nesplňují podmínku spojení, jsou zahrnuty do sady výsledků a výstupní sloupce, které odpovídají druhé tabulce, jsou kromě všech řádků vrácených vnitřním spojením nastaveny na hodnotu NULL.

Nápověda pro spojení

U SQL Serveru a služby SQL Database určuje, že optimalizátor dotazů SQL Serveru používá jeden tip spojení nebo algoritmus spouštění na spojení zadané v klauzuli FROM dotazu. Další informace naleznete v tématu Join Hints (Transact-SQL).

V případě systému Azure Synapse Analytics a Platform Platform System (PDW) se tyto rady spojení vztahují na vnitřní spojení ve dvou nekompatibilních sloupcích. Můžou zlepšit výkon dotazů omezením množství přesunu dat, ke kterému dochází během zpracování dotazů. Povolené tipy pro spojení pro Azure Synapse Analytics a PdW (Platform System) jsou následující:

ZMENŠIT

Zmenšuje počet řádků, které se mají přesunout pro tabulku na pravé straně spojení, aby byly dvě distribuce nekompatibilní tabulky kompatibilní. Tip REDUCE se také označuje jako tip pro střední spojení.

REPLIKOVAT

Způsobí replikaci hodnot ve sloupci spojení z tabulky na pravé straně spojení do všech uzlů. Tabulka vlevo je připojená k replikované verzi těchto sloupců.

PŘEROZDĚLIT

Vynutí rozdělení dvou zdrojů dat do sloupců zadaných v klauzuli JOIN. Pro distribuovanou tabulku provádí nástroj PdW (Analytics Platform System) přesun náhodného prohazování. U replikované tabulky provádí analýza systému PDW (Analytics Platform System) přesun oříznutí. Informace o těchto typech přesunů najdete v části "Operace plánu dotazů DMS" v článku "Principy plánů dotazů" v dokumentaci k produktu Analytics Platform System (PDW). Tento tip může zvýšit výkon, když plán dotazu používá přesun vysílání k vyřešení distribuce nekompatibilní spojení.

PŘIPOJIT

Označuje, že zadaná operace spojení by měla probíhat mezi zadanými zdroji tabulek nebo zobrazeními.

ZAPNUTO <search_condition>

Určuje podmínku, na které je spojení založeno. Podmínka může určit libovolný predikát, i když se často používají sloupce a relační operátory, například:

SELECT p.ProductID,
    v.BusinessEntityID
FROM Production.Product AS p
INNER JOIN Purchasing.ProductVendor AS v
    ON (p.ProductID = v.ProductID);

Pokud podmínka určuje sloupce, sloupce nemusí mít stejný název nebo stejný datový typ; Pokud však datové typy nejsou stejné, musí být kompatibilní nebo typy, které SQL Server může implicitně převést. Pokud datové typy nelze implicitně převést, podmínka musí datový typ explicitně převést pomocí funkce CONVERT.

Mohou existovat predikáty, které zahrnují pouze jednu z spojených tabulek v klauzuli ON. Takové predikáty mohou být také v klauzuli WHERE v dotazu. I když umístění takových predikátů neprovádí rozdíl pro vnitřní spojení, mohou způsobit jiný výsledek, když jsou zapojeny vnější spojení. Důvodem je to, že predikáty v klauzuli ON jsou použity na tabulku před spojením, zatímco klauzule WHERE je sémanticky použita na výsledek spojení.

Další informace o podmínkách hledání a predikátech najdete v tématupodmínky hledání (Transact-SQL).

KŘÍŽOVÉ SPOJENÍ

Určuje křížový součin dvou tabulek. Vrátí stejné řádky jako v případě, že nebyla zadána žádná klauzule WHERE ve starém stylu bez spojení typu SQL-92.

left_table_source { CROSS | VNĚJŠÍ } POUŽÍT right_table_source

Určuje, že right_table_source operátoru APPLY se vyhodnotí pro každý řádek left_table_source. Tato funkce je užitečná, když right_table_source obsahuje funkci s hodnotou tabulky, která přebírá hodnoty sloupců z left_table_source jako jeden z jejích argumentů.

Musí být zadána funkce CROSS nebo OUTER pomocí funkce APPLY. Při zadání funkce CROSS se při vyhodnocování right_table_source na zadaném řádku left_table_source nevygenerují žádné řádky a vrátí prázdnou sadu výsledků.

Při zadání funkce OUTER se pro každý řádek left_table_source vytvoří jeden řádek, i když right_table_source vyhodnotí tento řádek a vrátí prázdnou sadu výsledků.

Další informace najdete v části Poznámky.

left_table_source

Zdroj tabulky definovaný v předchozím argumentu Další informace najdete v části Poznámky.

right_table_source

Zdroj tabulky definovaný v předchozím argumentu Další informace najdete v části Poznámky.

Klauzule PIVOT

table_source KONTINGENČNÍ <pivot_clause>

Určuje, že table_source je kontingenční na základě pivot_column. table_source je výraz tabulky nebo tabulky. Výstup je tabulka, která obsahuje všechny sloupce table_source s výjimkou pivot_column a value_column. Sloupce table_sources výjimkou pivot_column a value_columnse nazývají sloupce seskupování kontingenčního operátoru. Další informace o funkci PIVOT a UNPIVOT naleznete v tématu Použití funkce PIVOT a FUNKCE UNPIVOT.

PIVOT provede operaci seskupení ve vstupní tabulce s ohledem na sloupce seskupení a vrátí jeden řádek pro každou skupinu. Výstup navíc obsahuje jeden sloupec pro každou hodnotu zadanou v column_list, která se zobrazí v pivot_columninput_table.

Další informace najdete v následujícím oddílu Poznámky.

aggregate_function

Systémová nebo uživatelem definovaná agregační funkce, která přijímá jeden nebo více vstupů. Agregační funkce by měla být invariantní na hodnoty null. Agregační funkce nebere v úvahu hodnoty null ve skupině při vyhodnocování agregační hodnoty.

Agregační funkce COUNT(*) není povolená.

value_column

Sloupec hodnoty operátoru PIVOT. Při použití s funkcemi UNPIVOT nemůže value_column být název existujícího sloupce ve vstupním table_source.

FOR pivot_column

Kontingenční sloupec operátoru PIVOT. pivot_column musí být typu implicitně nebo explicitně konvertibilní na nvarchar(). Tento sloupec nemůže být obrázku ani rowversion .

Při použití funkce UNPIVOT je pivot_column název výstupního sloupce, který se zužuje z table_source. V table_source s tímto názvem nemůže být existující sloupec.

IN ( column_list )

V klauzuli PIVOT se zobrazí hodnoty v pivot_column, které se stanou názvy sloupců výstupní tabulky. Seznam nemůže zadat žádné názvy sloupců, které již existují ve vstupním table_source, které jsou kontingenční.

V klauzuli UNPIVOT uvádí sloupce v table_source, které jsou zúženy na jeden pivot_column.

table_alias

Název aliasu výstupní tabulky pivot_table_alias je nutné zadat.

<UNPIVOT_CLAUSE> UNPIVOT

Určuje, že vstupní tabulka je zúžena z více sloupců v column_list do jednoho sloupce nazývaného pivot_column. Další informace o funkci PIVOT a UNPIVOT naleznete v tématu Použití funkce PIVOT a FUNKCE UNPIVOT.

OD <DATE_TIME>

platí pro: SQL Server 2016 (13.x) a novější verze a SQL Database.

Vrátí tabulku s jedním záznamem pro každý řádek obsahující hodnoty, které byly skutečné (aktuální) v zadaném bodu v čase v minulosti. Interně se provádí sjednocení mezi dočasnou tabulkou a její tabulkou historie a výsledky jsou filtrovány tak, aby vrátily hodnoty v řádku, které byly platné v okamžiku v čase určeném parametrem <date_time>. Hodnota řádku se považuje za platnou, pokud je hodnota system_start_time_column_name menší nebo rovna hodnotě parametru <date_time> a hodnota system_end_time_column_name je větší než hodnota parametru <date_time>.

FROM <start_date_time> to <end_date_time>

platí pro: SQL Server 2016 (13.x) a novější verze a SQL Database.

Vrátí tabulku s hodnotami pro všechny verze záznamů, které byly aktivní v zadaném časovém rozsahu, bez ohledu na to, zda začaly být aktivní před <start_date_time> hodnota parametru pro argument FROM nebo přestala být aktivní za hodnotou parametru <end_date_time> pro argument TO. Interně se provádí sjednocení mezi dočasnou tabulkou a její tabulkou historie a výsledky jsou filtrovány tak, aby vracely hodnoty pro všechny verze řádků, které byly aktivní kdykoli během zadaného časového rozsahu. Řádky, které se staly aktivní přesně na dolní hranici definované koncovým bodem FROM, jsou zahrnuty a řádky, které se staly aktivní přesně na horní hranici definované koncovým bodem TO, nejsou zahrnuty.

BETWEEN <start_date_time> AND <end_date_time>

platí pro: SQL Server 2016 (13.x) a novější verze a SQL Database.

Stejné jako výše v popisu FROM <start_date_time> TO <end_date_time> s výjimkou řádků, které se staly aktivními na horní hranici definované koncovým bodem <end_date_time>.

OBSAŽENÉ V (<start_date_time> , <end_date_time>)

platí pro: SQL Server 2016 (13.x) a novější verze a SQL Database.

Vrátí tabulku s hodnotami pro všechny verze záznamů, které byly otevřeny a uzavřeny v zadaném časovém rozsahu definovaném dvěma hodnotami data a času pro argument CONTAINED IN. Řádky, které byly aktivní přesně na dolní hranici nebo přestaly být aktivní přesně na horní hranici, jsou zahrnuty.

VŠICHNI

Vrátí tabulku s hodnotami ze všech řádků z aktuální tabulky i tabulky historie.

Poznámky

Klauzule FROM podporuje syntaxi SQL-92 pro spojené tabulky a odvozené tabulky. Syntaxe SQL-92 poskytuje operátory INNER, LEFT OUTER, RIGHT OUTER, FULL OUTER a CROSS join.

Klauzule UNION a JOIN v rámci klauzule FROM jsou podporovány v zobrazeních a v odvozených tabulkách a poddotazech.

Spojení sebe sama je tabulka, která je připojená k sobě. Operace vložení nebo aktualizace založené na vlastním spojení se řídí pořadím v klauzuli FROM.

Vzhledem k tomu, že SQL Server považuje statistiky distribuce a kardinality z propojených serverů, které poskytují statistiky distribuce sloupců, není k vzdálenému vyhodnocení spojení nutné. Procesor dotazů SQL Serveru považuje vzdálené statistiky a určuje, jestli je vhodná strategie vzdáleného připojení. Nápověda ke vzdálenému spojení je užitečná pro poskytovatele, kteří neposkytují statistiky distribuce sloupců.

Použít APPLY

Levý i pravý operand operátoru APPLY jsou výrazy tabulky. Hlavním rozdílem mezi těmito operandy je, že right_table_source může použít funkci s hodnotou tabulky, která přebírá sloupec z left_table_source jako jeden z argumentů funkce. left_table_source může obsahovat funkce s hodnotami tabulky, ale nemůže obsahovat argumenty, které jsou sloupce z right_table_source.

Operátor APPLY funguje následujícím způsobem k vytvoření zdroje tabulky pro klauzuli FROM:

  1. Vyhodnotí right_table_source pro každý řádek left_table_source a vytvoří sady řádků.

    Hodnoty v right_table_source závisí na left_table_source. right_table_source lze reprezentovat přibližně tímto způsobem: TVF(left_table_source.row), kde TVF je funkce s hodnotou tabulky.

  2. Kombinuje sady výsledků vytvořené pro každý řádek při vyhodnocování right_table_source s left_table_source provedením operace UNION ALL.

    Seznam sloupců vytvořených výsledkem operátoru APPLY je sada sloupců z left_table_source, která je kombinována se seznamem sloupců z right_table_source.

Použití kontingenční tabulky a funkce UNPIVOT

pivot_column a value_column seskupují sloupce, které používá operátor PIVOT. Pivot se řídí následujícím postupem získání výstupní sady výsledků:

  1. Provede funkci GROUP BY na svém input_table proti sloupcům seskupení a vytvoří jeden výstupní řádek pro každou skupinu.

    Seskupování sloupců ve výstupním řádku získá odpovídající hodnoty sloupců pro danou skupinu v input_table.

  2. Vygeneruje hodnoty pro sloupce v seznamu sloupců pro každý výstupní řádek provedením následujících kroků:

    1. Seskupování dalších řádků vygenerovaných v nástroji GROUP BY v předchozím kroku proti pivot_column.

      Pro každý výstupní sloupec v column_listvyberte podskupinu, která splňuje podmínku:

      pivot_column = CONVERT(<data type of pivot_column>, 'output_column')

    2. aggregate_function se vyhodnotí jako value_column v této podskupině a výsledek se vrátí jako hodnota odpovídajícího output_column. Pokud je podskupina prázdná, SQL Server vygeneruje hodnotu null pro tuto output_column. Pokud je agregační funkce POČET a podskupina je prázdná, vrátí se nula (0).

Poznámka

Identifikátory sloupců v klauzuli UNPIVOT se řídí kolací katalogu. Pro SQL Database je kolace vždy SQL_Latin1_General_CP1_CI_AS. U částečně obsažených databází SQL Serveru je kolace vždy Latin1_General_100_CI_AS_KS_WS_SC. Pokud se sloupec zkombinuje s jinými sloupci, vyžaduje se kompletovací klauzule (COLLATE DATABASE_DEFAULT), aby nedocházelo ke konfliktům.

Další informace o funkci PIVOT a UNPIVOT včetně příkladů najdete v tématu Použití kontingenční tabulky a funkce UNPIVOT.

Dovolení

Vyžaduje oprávnění pro příkaz DELETE, SELECT nebo UPDATE.

Příklady

A. Použití klauzule FROM

Následující příklad načte sloupce TerritoryID a Name z tabulky SalesTerritory v ukázkové databázi AdventureWorks2022.

SELECT TerritoryID,
    Name
FROM Sales.SalesTerritory
ORDER BY TerritoryID;

Tady je sada výsledků.

TerritoryID Name
----------- ------------------------------
1           Northwest
2           Northeast
3           Central
4           Southwest
5           Southeast
6           Canada
7           France
8           Germany
9           Australia
10          United Kingdom
(10 row(s) affected)

B. Použití tipů optimalizátoru TABLOCK a HOLDLOCK

Následující částečná transakce ukazuje, jak umístit explicitní sdílený zámek tabulky na Employee a jak číst index. Zámek se uchovává v celé transakci.

BEGIN TRANSACTION

SELECT COUNT(*)
FROM HumanResources.Employee WITH (TABLOCK, HOLDLOCK);

C. Použití syntaxe SQL-92 CROSS JOIN

Následující příklad vrátí křížový součin dvou tabulek Employee a Department v databázi AdventureWorks2022. Vrátí se seznam všech možných kombinací BusinessEntityID řádků a všech Department řádků názvů.

SELECT e.BusinessEntityID,
    d.Name AS Department
FROM HumanResources.Employee AS e
CROSS JOIN HumanResources.Department AS d
ORDER BY e.BusinessEntityID,
    d.Name;

D. Použití syntaxe SQL-92 FULL OUTER JOIN

Následující příklad vrátí název produktu a všechny odpovídající prodejní objednávky v tabulce SalesOrderDetail v databázi AdventureWorks2022. Vrátí také všechny prodejní objednávky, které nemají žádný produkt uvedený v tabulce Product, a všechny produkty s jinou prodejní objednávkou, než je ta uvedená v tabulce Product.

-- The OUTER keyword following the FULL keyword is optional.
SELECT p.Name,
    sod.SalesOrderID
FROM Production.Product AS p
FULL JOIN Sales.SalesOrderDetail AS sod
    ON p.ProductID = sod.ProductID
ORDER BY p.Name;

E. Použití syntaxe SQL-92 LEFT OUTER JOIN

Následující příklad spojí dvě tabulky na ProductID a zachová chybějící řádky z levé tabulky. Tabulka Product se shoduje s tabulkou SalesOrderDetail v ProductID sloupcích v každé tabulce. V sadě výsledků se zobrazí všechny produkty, seřazené a nevyřazené.

SELECT p.Name,
    sod.SalesOrderID
FROM Production.Product AS p
LEFT OUTER JOIN Sales.SalesOrderDetail AS sod
    ON p.ProductID = sod.ProductID
ORDER BY p.Name;

F. Použití syntaxe SQL-92 INNER JOIN

Následující příklad vrátí všechny názvy produktů a ID prodejních objednávek.

-- By default, SQL Server performs an INNER JOIN if only the JOIN
-- keyword is specified.
SELECT p.Name,
    sod.SalesOrderID
FROM Production.Product AS p
INNER JOIN Sales.SalesOrderDetail AS sod
    ON p.ProductID = sod.ProductID
ORDER BY p.Name;

G. Použití syntaxe SQL-92 RIGHT OUTER JOIN

Následující příklad spojí dvě tabulky na TerritoryID a zachová chybějící řádky z pravé tabulky. Tabulka SalesTerritory se shoduje s tabulkou SalesPerson ve sloupci TerritoryID v každé tabulce. V sadě výsledků se zobrazí všichni prodejci bez ohledu na to, jestli mají přiřazenou oblast.

SELECT st.Name AS Territory,
    sp.BusinessEntityID
FROM Sales.SalesTerritory AS st
RIGHT OUTER JOIN Sales.SalesPerson AS sp
    ON st.TerritoryID = sp.TerritoryID;

H. Použití tipů pro spojení HASH a MERGE

Následující příklad provede spojení se třemi tabulkami mezi Product, ProductVendora Vendor tabulky pro vytvoření seznamu produktů a jejich dodavatelů. Optimalizátor dotazů spojí Product a ProductVendor (p a pv) pomocí spojení MERGE. Dále jsou výsledky spojení Product a ProductVendor MERGE (p a pv) spojené s tabulkou Vendor pro vytvoření (p a pv) a v.

Důležitý

Po zadání nápovědy ke spojení už není klíčové slovo INNER volitelné a musí být explicitně uvedeno, aby bylo možné provést INNER JOIN.

SELECT p.Name AS ProductName,
    v.Name AS VendorName
FROM Production.Product AS p
INNER MERGE JOIN Purchasing.ProductVendor AS pv
    ON p.ProductID = pv.ProductID
INNER HASH JOIN Purchasing.Vendor AS v
    ON pv.BusinessEntityID = v.BusinessEntityID
ORDER BY p.Name,
    v.Name;

Já. Použití odvozené tabulky

Následující příklad používá odvozenou tabulku, SELECT příkaz za klauzulí FROM, k vrácení křestního jména a příjmení všech zaměstnanců a měst, ve kterých žijí.

SELECT RTRIM(p.FirstName) + ' ' + LTRIM(p.LastName) AS Name,
    d.City
FROM Person.Person AS p
INNER JOIN HumanResources.Employee e
    ON p.BusinessEntityID = e.BusinessEntityID
INNER JOIN (
    SELECT bea.BusinessEntityID,
        a.City
    FROM Person.Address AS a
    INNER JOIN Person.BusinessEntityAddress AS bea
        ON a.AddressID = bea.AddressID
    ) AS d
    ON p.BusinessEntityID = d.BusinessEntityID
ORDER BY p.LastName,
    p.FirstName;

J. Použití TABLEAMPLE ke čtení dat ze vzorku řádků v tabulce

Následující příklad používá TABLESAMPLE v klauzuli FROM k vrácení přibližně 10 procent všech řádků v tabulce Customer.

SELECT *
FROM Sales.Customer TABLESAMPLE SYSTEM(10 PERCENT);

K. Použít APPLY

Následující příklad předpokládá, že v databázi existují následující tabulky a funkce s hodnotou tabulky:

Název objektu Názvy sloupců
Oddělení DeptID, DivisionID, DeptName, DeptMgrID
EmpMgr MgrID, EmpID
Zaměstnanci EmpID, EmpLastName, EmpFirstName, EmpSalary
GetReports(MgrID) EmpID, EmpLastName, EmpSalary

Funkce GetReports hodnotná tabulkou vrátí seznam všech zaměstnanců, kteří hlásí přímo nebo nepřímo zadané MgrID.

Příklad používá APPLY k vrácení všech oddělení a všech zaměstnanců v tomto oddělení. Pokud konkrétní oddělení nemá žádné zaměstnance, nebudou pro toto oddělení vráceny žádné řádky.

SELECT DeptID,
    DeptName,
    DeptMgrID,
    EmpID,
    EmpLastName,
    EmpSalary
FROM Departments d
CROSS APPLY dbo.GetReports(d.DeptMgrID);

Pokud chcete, aby dotaz vytvořil řádky pro tato oddělení bez zaměstnanců, což vytvoří hodnoty null pro EmpID, EmpLastName a EmpSalary sloupce, použijte místo toho OUTER APPLY.

SELECT DeptID,
    DeptName,
    DeptMgrID,
    EmpID,
    EmpLastName,
    EmpSalary
FROM Departments d
OUTER APPLY dbo.GetReports(d.DeptMgrID);

L. Použití KŘÍŽOVÉHO POUŽITÍ

Následující příklad načte snímek všech plánů dotazů umístěných v mezipaměti plánu dotazováním zobrazení sys.dm_exec_cached_plans dynamické správy pro načtení popisovačů plánu všech plánů dotazů v mezipaměti. Potom je zadán operátor CROSS APPLY pro předání popisovačů plánu sys.dm_exec_query_plan. Výstup xml Showplan pro každý plán aktuálně v mezipaměti plánu je ve sloupci query_plan vrácené tabulky.

USE master;
GO

SELECT dbid,
    object_id,
    query_plan
FROM sys.dm_exec_cached_plans AS cp
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle);
GO

M. Použití for SYSTEM_TIME

platí pro: SQL Server 2016 (13.x) a novější verze a SQL Database.

Následující příklad používá argument FOR SYSTEM_TIME AS OF date_time_literal_or_variable k vrácení řádků tabulky, které byly skutečné (aktuální) od 1. ledna 2014.

SELECT DepartmentNumber,
    DepartmentName,
    ManagerID,
    ParentDepartmentNumber
FROM DEPARTMENT
FOR SYSTEM_TIME AS OF '2014-01-01'
WHERE ManagerID = 5;

Následující příklad používá argument FOR SYSTEM_TIME FROM date_time_literal_or_variable TO date_time_literal_or_variable k vrácení všech řádků, které byly aktivní během období definovaného od 1. ledna 2013 a končící 1. lednem 2014, s výjimkou horní hranice.

SELECT DepartmentNumber,
    DepartmentName,
    ManagerID,
    ParentDepartmentNumber
FROM DEPARTMENT
FOR SYSTEM_TIME FROM '2013-01-01' TO '2014-01-01'
WHERE ManagerID = 5;

Následující příklad používá argument FOR SYSTEM_TIME BETWEEN date_time_literal_or_variable AND date_time_literal_or_variable k vrácení všech řádků, které byly aktivní během období definovaného od 1. ledna 2013 a končící 1. lednem 2014 včetně horní hranice.

SELECT DepartmentNumber,
    DepartmentName,
    ManagerID,
    ParentDepartmentNumber
FROM DEPARTMENT
FOR SYSTEM_TIME BETWEEN '2013-01-01' AND '2014-01-01'
WHERE ManagerID = 5;

Následující příklad používá argument FOR SYSTEM_TIME OBSAŽENÉ V (date_time_literal_or_variable, date_time_literal_or_variable) k vrácení všech řádků, které byly otevřeny a uzavřeny během období definovaného od 1. ledna 2013 a končí 1. ledna 2014.

SELECT DepartmentNumber,
    DepartmentName,
    ManagerID,
    ParentDepartmentNumber
FROM DEPARTMENT
FOR SYSTEM_TIME CONTAINED IN ('2013-01-01', '2014-01-01')
WHERE ManagerID = 5;

Následující příklad používá proměnnou místo literálu k zadání hodnot hranic kalendářního data pro dotaz.

DECLARE @AsOfFrom DATETIME2 = DATEADD(month, -12, SYSUTCDATETIME());
DECLARE @AsOfTo DATETIME2 = DATEADD(month, -6, SYSUTCDATETIME());

SELECT DepartmentNumber,
    DepartmentName,
    ManagerID,
    ParentDepartmentNumber
FROM DEPARTMENT
FOR SYSTEM_TIME
FROM @AsOfFrom TO @AsOfTo
WHERE ManagerID = 5;

Příklady: Azure Synapse Analytics a Analytický platformový systém (PDW)

N. Použití syntaxe INNER JOIN

Následující příklad vrátí sloupce SalesOrderNumber, ProductKeya EnglishProductName ze FactInternetSales a DimProduct tabulek, kde klíč spojení ProductKeyodpovídá v obou tabulkách. SalesOrderNumber a EnglishProductName sloupce existují pouze v jedné z tabulek, takže není nutné specifikovat alias tabulky s těmito sloupci, jak je znázorněno; tyto aliasy jsou zahrnuty pro čitelnost. Slovo AS před názvem aliasu není povinné, ale doporučuje se pro čitelnost a dodržování standardu ANSI.

-- Uses AdventureWorks
  
SELECT fis.SalesOrderNumber,
    dp.ProductKey,
    dp.EnglishProductName
FROM FactInternetSales AS fis
INNER JOIN DimProduct AS dp
    ON dp.ProductKey = fis.ProductKey;

Vzhledem k tomu, že pro vnitřní spojení není nutné klíčové slovo INNER, může být tento stejný dotaz napsán jako:

-- Uses AdventureWorks
  
SELECT fis.SalesOrderNumber,
    dp.ProductKey,
    dp.EnglishProductName
FROM FactInternetSales AS fis
INNER JOIN DimProduct AS dp
    ON dp.ProductKey = fis.ProductKey;

K omezení výsledků je možné použít také klauzuli WHERE s tímto dotazem. Tento příklad omezuje výsledky na SalesOrderNumber hodnoty vyšší než SO5000:

-- Uses AdventureWorks
  
SELECT fis.SalesOrderNumber,
    dp.ProductKey,
    dp.EnglishProductName
FROM FactInternetSales AS fis
INNER JOIN DimProduct AS dp
    ON dp.ProductKey = fis.ProductKey
WHERE fis.SalesOrderNumber > 'SO50000'
ORDER BY fis.SalesOrderNumber;

O. Použití syntaxe LEFT OUTER JOIN a RIGHT OUTER JOIN

Následující příklad spojí tabulky FactInternetSales a DimProduct ve sloupcích ProductKey. Syntaxe levého vnějšího spojení zachovává chybějící řádky z levé tabulky (FactInternetSales). Vzhledem k tomu, že tabulka FactInternetSales neobsahuje žádné ProductKey hodnoty, které neodpovídají DimProduct tabulce, vrátí tento dotaz stejné řádky jako první příklad vnitřního spojení dříve v tomto článku.

-- Uses AdventureWorks
  
SELECT fis.SalesOrderNumber,
    dp.ProductKey,
    dp.EnglishProductName
FROM FactInternetSales AS fis
LEFT OUTER JOIN DimProduct AS dp
    ON dp.ProductKey = fis.ProductKey;

Tento dotaz lze také zapsat bez klíčového slova OUTER.

V pravých vnějších spojeních se zachovají chybějící řádky z pravé tabulky. Následující příklad vrátí stejné řádky jako levý příklad vnějšího spojení výše.

-- Uses AdventureWorks
  
SELECT fis.SalesOrderNumber,
    dp.ProductKey,
    dp.EnglishProductName
FROM DimProduct AS dp
RIGHT OUTER JOIN FactInternetSales AS fis
    ON dp.ProductKey = fis.ProductKey;

Následující dotaz používá DimSalesTerritory tabulku jako levou tabulku v levém vnějším spojení. Načte hodnoty SalesOrderNumber z tabulky FactInternetSales. Pokud pro konkrétní SalesTerritoryKeyneexistují žádné objednávky, vrátí dotaz hodnotu NULL pro SalesOrderNumber pro daný řádek. Tento dotaz je seřazený podle sloupce SalesOrderNumber, aby se všechny hodnoty NUL v tomto sloupci zobrazovaly v horní části výsledků.

-- Uses AdventureWorks
  
SELECT dst.SalesTerritoryKey,
    dst.SalesTerritoryRegion,
    fis.SalesOrderNumber
FROM DimSalesTerritory AS dst
LEFT OUTER JOIN FactInternetSales AS fis
    ON dst.SalesTerritoryKey = fis.SalesTerritoryKey
ORDER BY fis.SalesOrderNumber;

Tento dotaz se dá přepsat pravým vnějším spojením, aby se načetly stejné výsledky:

-- Uses AdventureWorks
  
SELECT dst.SalesTerritoryKey,
    dst.SalesTerritoryRegion,
    fis.SalesOrderNumber
FROM FactInternetSales AS fis
RIGHT OUTER JOIN DimSalesTerritory AS dst
    ON fis.SalesTerritoryKey = dst.SalesTerritoryKey
ORDER BY fis.SalesOrderNumber;

P. Použití syntaxe FULL OUTER JOIN

Následující příklad ukazuje úplné vnější spojení, které vrátí všechny řádky z obou spojených tabulek, ale vrátí hodnotu NULL pro hodnoty, které se neshodují z druhé tabulky.

-- Uses AdventureWorks
  
SELECT dst.SalesTerritoryKey,
    dst.SalesTerritoryRegion,
    fis.SalesOrderNumber
FROM DimSalesTerritory AS dst
FULL JOIN FactInternetSales AS fis
    ON dst.SalesTerritoryKey = fis.SalesTerritoryKey
ORDER BY fis.SalesOrderNumber;

Tento dotaz lze také zapsat bez klíčového slova OUTER.

-- Uses AdventureWorks
  
SELECT dst.SalesTerritoryKey,
    dst.SalesTerritoryRegion,
    fis.SalesOrderNumber
FROM DimSalesTerritory AS dst
FULL JOIN FactInternetSales AS fis
    ON dst.SalesTerritoryKey = fis.SalesTerritoryKey
ORDER BY fis.SalesOrderNumber;

Q. Použití syntaxe CROSS JOIN

Následující příklad vrátí křížový součin FactInternetSales a DimSalesTerritory tabulek. Vrátí se seznam všech možných kombinací SalesOrderNumber a SalesTerritoryKey. Všimněte si absence klauzule ON v dotazu křížového spojení.

-- Uses AdventureWorks
  
SELECT dst.SalesTerritoryKey,
    fis.SalesOrderNumber
FROM DimSalesTerritory AS dst
CROSS JOIN FactInternetSales AS fis
ORDER BY fis.SalesOrderNumber;

R. Použití odvozené tabulky

Následující příklad používá odvozenou tabulku (příkaz SELECT za klauzulí FROM) k vrácení CustomerKey a LastName sloupců všech zákazníků v tabulce DimCustomer s BirthDate hodnotami pozdějšími než 1. ledna 1970 a příjmením Smith.

-- Uses AdventureWorks
  
SELECT CustomerKey,
    LastName
FROM (
    SELECT *
    FROM DimCustomer
    WHERE BirthDate > '01/01/1970'
    ) AS DimCustomerDerivedTable
WHERE LastName = 'Smith'
ORDER BY LastName;

S. Příklad nápovědy ke spojení REDUCE

Následující příklad používá nápovědu REDUCE spojení ke změně zpracování odvozené tabulky v dotazu. Při použití nápovědy REDUCE spojení v tomto dotazu se fis.ProductKey promítnou, replikují a zvýrazní a pak připojí k DimProduct během náhodného prohazování DimProduct na ProductKey. Výsledná odvozená tabulka se distribuuje na fis.ProductKey.

-- Uses AdventureWorks
  
SELECT SalesOrderNumber
FROM (
    SELECT fis.SalesOrderNumber,
        dp.ProductKey,
        dp.EnglishProductName
    FROM DimProduct AS dp
    INNER REDUCE JOIN FactInternetSales AS fis
        ON dp.ProductKey = fis.ProductKey
    ) AS dTable
ORDER BY SalesOrderNumber;

T. Příklad nápovědy k replikaci spojení

Tento další příklad ukazuje stejný dotaz jako v předchozím příkladu s tím rozdílem, že místo nápovědy pro spojení REDUCE se používá tip REPLICATE spojení. Použití REPLICATE nápovědy způsobí, že se hodnoty ve sloupci ProductKey (spojování) z tabulky FactInternetSales replikují do všech uzlů. Tabulka DimProduct je připojená k replikované verzi těchto hodnot.

-- Uses AdventureWorks

SELECT SalesOrderNumber
FROM (
    SELECT fis.SalesOrderNumber,
        dp.ProductKey,
        dp.EnglishProductName
    FROM DimProduct AS dp
    INNER REPLICATE JOIN FactInternetSales AS fis
        ON dp.ProductKey = fis.ProductKey
    ) AS dTable
ORDER BY SalesOrderNumber;

U. Pomocí nápovědy k redistribuci zaručte přesun pro distribuci nekompatibilní spojení.

Následující dotaz používá nápovědu k dotazu REDISTRIBUTE pro distribuci nekompatibilní spojení. To zaručuje, že optimalizátor dotazů používá v plánu dotazu přesun shuffle. To také zaručuje, že plán dotazu nebude používat přesun všesměrového vysílání, který přesune distribuovanou tabulku do replikované tabulky.

V následujícím příkladu vynutí tip REDISTRIBUTE pohyb v tabulce FactInternetSales, protože ProductKey je distribuční sloupec pro DimProduct a není distribučním sloupcem FactInternetSales.

-- Uses AdventureWorks
  
SELECT dp.ProductKey,
    fis.SalesOrderNumber,
    fis.TotalProductCost
FROM DimProduct AS dp
INNER REDISTRIBUTE JOIN FactInternetSales AS fis
    ON dp.ProductKey = fis.ProductKey;

V. Použití TABLEAMPLE ke čtení dat ze vzorku řádků v tabulce

Následující příklad používá TABLESAMPLE v klauzuli FROM k vrácení přibližně 10 procent všech řádků v tabulce Customer.

SELECT *
FROM Sales.Customer TABLESAMPLE SYSTEM(10 PERCENT);
  • CONTAINSTABLE (Transact-SQL)
  • FREETEXTTABLE (Transact-SQL)
  • INSERT (Transact-SQL)
  • OPENQUERY (Transact-SQL)
  • OPENROWSET (Transact-SQL)
  • operátory (Transact-SQL)
  • WHERE (Transact-SQL)