SELECT
[DISTINCT] [* | [ expression [[AS] column_name_alias] [, ...] ]
[INTO #temp_table_name]
[FROM table_name]
[WHERE condition [, ...] ]
[GROUP BY expression [, ...] ]
[HAVING condition [, ...] ]
[ORDER BY expression [ASC | DESC] [, ...] ]
[LIMIT row_count]
[WITH (option_name=option_value] [, ...]) ] [;]
option_name:=IDENTIFIER
option_value:= NUMBER | STRING
SELECT [DISTINCT] [* | [ expression [[AS] column_name_alias] [, ...] ]
FROM #temp_table_name
[[INNER | OUTER | CROSS] JOIN #temp_table_name [alias] ON condition
[join_statement]
[join_statement]
...
]
[WHERE condition [, ...] ]
[GROUP BY expression [, ...] ]
[HAVING condition [, ...] ]
[ORDER BY expression [ASC | DESC] [, ...] ]
[LIMIT row_count]
select_into_temp;
[select_into_temp;]
[select_into_temp;]
...
select_from_temp_table;
--some comment in single line
|
/* some block comment */
select_from_temp_table_1
UNION | UNION ALL
select_from_temp_table_2
[UNION | UNION ALL]
select_from_temp_table_3
...
...
CREATE PROCEDURE proc_name
[@parameter_name [= 'Some Default Value'] ]
[@parameter_name [= 'Some Default Value'] ]
...
...
AS
sql-statement;
[sql-statement | sql-temp-table-usage] ;
[sql-statement | sql-temp-table-usage] ;
...
...
Executing PROCEDURE
EXEC proc_name [value1] [,value2] ... [,valueN]
Deleting PROCEDURE
DROP PROCEDURE proc_name
SELECT * FROM "feed.entry"
WITH (SRC='https://services.odata.org/Northwind/Northwind.svc/Orders')
SELECT * FROM $ WITH (SRC='C:\Data\cust-1.xml')
SELECT * FROM $
WITH (
SRC='C:\Data\cust*-?.xml'
--,RECURSIVE='True' --Include files from sub folder
)
SELECT * FROM [data.row]
WITH (
--enter path in SRC or use static value in DATA'
--SRC='http://some/api/data.xml'
--SRC='C:\somefile.xml'
--SRC='C:\some*.xml'
DATA='
<data>
<row><id>1</id><name>AAA</name></row>
<row><id>2</id><name>BBB</name></row>
</data>'
,ElementsToTreatAsArray='row' --if you don't specify this option then your query may fail when only 1 <row> tag is found (use comma for multiple names e.g. order,item,row).
)
SELECT * FROM [data.row]
WITH (
--enter path in SRC or use static value in DATA'
--SRC='http://some/api/data.xml'
--SRC='C:\somefile.xml'
--SRC='C:\some*.xml'
DATA=@'<data>\r\n<row><id>1</id><name>AA\u0041</name></row>\r\n<row><id>2</id><name>BBB</name></row>\r\n</data>'
,ElementsToTreatAsArray='row' --if you don't specify this option then your query may fail when only 1 <row> tag is found (use comma for multiple names e.g. order,item,row).
)
SELECT * FROM "Root.value"
WITH (
Data='cmd:>powershell -executionpolicy bypass -Command "[System.IO.StreamReader]::new((Invoke-WebRequest -URI https://zappysys.com/downloads/files/test/invoices.xml).RawContentStream).ReadToEnd()"'
)
--Credentials via Query
SELECT * FROM $ WITH (SRC='http://httpbin.org/xml'
,DataConnectionType='HTTP'
,CredentialType='Basic'
,UserName='user1'
,Password='pass123')
--Credentials inside connection string [Use Data source setup grid >> Select Connection = HTTP (Click Configure) >> Set Credential type=Basic, UserId=user1, Password=pass123]
--SELECT * FROM $ WITH (SRC='http://httpbin.org/xml')
--Credentials via Query
SELECT * FROM $
WITH (SRC='http://yourhost/some-service',DataConnectionType='HTTP',CredentialType='Ntlm')
--Credentials inside connection string [Use Data source setup grid >> Authentication type=Ntlm]
--SELECT * FROM $ WITH (SRC='http://yourhost/some-service')
--Credentials via Query
SELECT * FROM $ WITH (
SRC='http://yourhost/api/some-service'
,DataConnectionType='OAuth'
,UseCustomApp='True'
,OAuthVersion='OAuth2'
,AuthUrl='https://yourhost/api/authorize'
,TokenUrl='https://yourhost/api/token'
,ClientId='xxxxxxxxxxx'
,ClientSecret='xxxxxxxxxxxxx'
,AccessToken='xxxxxxxxxxx'
,RefreshToken='xxxxxxxxxxx' --//This is only obtained from UI by clicking Generate Token Button
)
--Credentials inside connection string [Use Data source setup grid >> Authentication type=OAuth >> Click OAuth Button to configure connection]
SELECT * FROM $ WITH (SRC='http://yourhost/api/some-service')
--Credentials via Query
--Check this link to learn more about how to generate ClientId / ClientSecret >> https://zappysys.com/blog/register-google-oauth-application-get-clientid-clientsecret/
--To get Access Token and Refresh Token >> Goto properties grid >> Change Authentication type=OAuth >> Click OAuth Button to configure connection >> Select Provider='Google' >> Use Custom App >> Select Scope and click Generate Token >> Save tokens to file
SELECT * FROM $ WITH
(
SRC='https://www.googleapis.com/analytics/v3/metadata/ga/columns'
,UseCustomApp='True'
,DataConnectionType='OAuth'
,ServiceProvider='Google'
,ClientId='3855xxxxxx-xxxxxxxxxxxxxxxxx.apps.googleusercontent.com'
,ClientSecret='qF7axxxxxxxxxxxWfs'
,AccessToken='ya29.GlsxxxxxxxxxIam'
,RefreshToken='1/pFOxxxxxxxxxxgU' --//This is only obtained from UI by clicking Generate Token Button
)
--Credentials inside connection string [Use Data source setup grid >> Authentication type=OAuth >> Click OAuth Button to configure connection]
SELECT * FROM $ WITH (SRC='https://www.googleapis.com/analytics/v3/metadata/ga/columns')
SELECT * FROM "feed.entry" WITH (SRC='https://services.odata.org/Northwind/Northwind.svc/Orders',DataFormat='OData')
SELECT * FROM $
WITH(
ElementsToTreatAsArray='urn:Row'
,Src='https://zappysys.com/downloads/files/test/soap-getdata.aspx'
,DataConnectionType='HTTP'
,AuthScheme='{none}'
,TokenUrl='https://zappysys.com/downloads/files/test/soap-login.aspx'
,TokenRequestData='
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com">
<soapenv:Body>
<urn:login>
<urn:username>[$userid$]</urn:username>
<urn:password>[$password$]</urn:password>
</urn:login>
</soapenv:Body>
</soapenv:Envelope>'
,TokenRequestMethod='POST'
,TokenResponseContentFilter='//*[local-name() = ''sessionid'']'
,TokenRequestHeaders='Content-Type:text/xml|Accept:*/*|Cache-Control:no-cache'
,TokenResponseContentType='Xml'
,UserName='MyUser001'
,Password='P@$$w0rdAAc12'
,CredentialType='TokenDynamic'
,Filter='$.soapenv:Envelope.soapenv:Body.urn:Row[*]'
,RequestData='
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:partner.soap.sforce.com">
<soapenv:Body>
<urn:sessionid>[$token$]</urn:sessionid>
</soapenv:Body>
</soapenv:Envelope>'
,Header='Content-Type: text/xml;charset=UTF-8 || SOAPAction: "https://zappysys.com/soap-getdata" || Accept: */* || Cache-Control: no-cache'
,RequestMethod='POST'
)
SELECT * FROM "root.element"
WITH (
SRC='https://zappysys.com/downloads/files/test/page-xml.aspx?page=1&mode=DetectBasedOnResponseStatusCode'
,PagingMode='ByUrlParameter'
,PagingByUrlAttributeName='page'
,PagingByUrlEndStrategy='DetectBasedOnResponseStatusCode'
,PagingByUrlCheckResponseStatusCode=401
,IncrementBy=1
)
SELECT * FROM $
WITH (
SRC='https://zappysys.com/downloads/files/test/cust-<%page%>.xml'
,PagingMode='ByUrlPath'
,Filter='$.root.element[*]'
,PagingByUrlAttributeName='<%page%>'
,PagingByUrlEndStrategy='DetectBasedOnRecordCount'
,IncrementBy=1
)
SELECT
c.custid,c.name,c.city
,o.orderid,o.orderdate,o.total
/* ,i.itemid,i.qty,i.shipped */
FROM $
WITH(
--1st level (root)--
src='https://zappysys.com/downloads/files/test/join/customers.xml'
,NextUrlAttributeOrExpr='$.root.nextpage'
,ElementsToTreatAsArray='element'
,filter='$.root.customers.element[*]'
,alias='c'
,WaitTimeMs='500'
--2nd level--
--You can pass parent column to child URL using placeholder [$parent_alias.parent_col_name$] syntax (e.g. [$c.custid$] )
,join1_src='https://zappysys.com/downloads/files/test/join/c[$c.custid$]/orders.xml'
,join1_NextUrlAttributeOrExpr='$.root.nextpage'
,join1_ElementsToTreatAsArray='element'
,join1_filter='$.root.orders.element[*]'
,join1_alias='o'
,join1_WaitTimeMs='500'
/*
--3rd level--
--You can pass parent column to child URL using placeholder [$parent_alias.parent_col_name$] syntax (e.g. [$c.custid$] and [$o.orderid$])
--You can also use placeholder functions e.g. [$c.firstname,FUN_TRIM$] --see this link for list of functions https://zappysys.com/onlinehelp/odbc-powerpack/scr/odbc-format-static-placeholders.htm
,join2_src='https://zappysys.com/downloads/files/test/join/c[$c.custid$]/o[$o.orderid$]/items.xml'
,join2_NextUrlAttributeOrExpr='$.root.nextpage'
,join2_ElementsToTreatAsArray='element'
,join2_filter='$.root.items.element[*]'
,join2_alias='i'
,join2_WaitTimeMs='500'
--maximum 7 levels deep you can go. Any attributes allowed in WITH clause can be prefixed by by joinN_xxx
-- join3_xxxxx, join4_xxxxxx .......... join7_xxxxx
*/
)
SELECT b.* FROM $
WITH(
--1st level (root)--
src='https://zappysys.com/downloads/files/test/nested-base64.xml'
,filter='$.soap:Envelope.soap:Body'
,alias='a'
--2nd level--
,join1_data='[$a.Result,FUN_BASE64DEC$]'
,join1_ElementsToTreatAsArray='Row'
,join1_filter='$.Data.Row[*]'
,join1_alias='b'
)
SELECT
_pid,q._rid
, r.custid as CUST_ID, r.city as CUST_CITY
, q.VAL1, q.VAL2, q.VAL3, q.DESCR
FROM $
ORDER BY _pid,q._rid
WITH (
SRC='https://zappysys.com/downloads/files/test/join/customers.xml'
,ElementsToTreatAsArray= 'element'
,filter= '$.root.customers.element[*]'
,ALIAS='r'
,JOIN1_DATA='<ORDERS>
<ROW><VAL1>HINTROW</VAL1><VAL2>000100</VAL2><VAL3>000100</VAL3><DESCR>Some notes1</DESCR></ROW>
<ROW><VAL1>5023</VAL1><VAL2>000200</VAL2><VAL3>000200</VAL3><DESCR>Some notes2</DESCR></ROW>
<ROW><VAL1>0000</VAL1><VAL2>000300</VAL2><VAL3>000300</VAL3><DESCR>Some notes3</DESCR></ROW>
</ORDERS>'
,JOIN1_FILTER='$.ORDERS.ROW[*]'
,JOIN1_IncludeParentColumns='False'
,JOIN1_ALIAS='q'
--metadata for final output (include column, type, length for output of SELECT).
--This meta does not perform type casting
,Meta='[
{Name: "_rid",Type: "Int32"},
{Name: "_pid",Type: "Int32"},
{Name: "CUST_ID",Type: "String",Length: 100},
{Name: "CUST_CITY",Type: "String",Length: 100},
{Name: "VAL1",Type: "String",Length: 100},
{Name: "VAL2",Type: "Int32"},
{Name: "VAL3",Type: "String"},
{Name: "DESCR",Type: "String",Length: 254}
]'
--child level1 metadata (length not needed). Datatype used below may perform some type casting ---
,JOIN1_meta='[
{Name: "VAL1",Type: "String"},
{Name: "VAL2",Type: "Int32"},
{Name: "VAL3",Type: "String"},
{Name: "DESCR",Type: "String"}
]'
)
select a.url,b.data,file_write_binary(base64_to_bytes(b.data) ,'c:\temp\' || name ) as bytes_written
from $
WITH (
SRC='https://zappysys.com/downloads/files/test/imagelist.xml',
FILTER='$.doc.list[*]',
ALIAS='a',
JOIN1_SRC='[$a.url$]',
JOIN1_ALIAS='b',
JOIN1_SaveContentAsBinary='true'
)
select a.name,c.*
from $
WITH (
--Step1: Get List of URLs to download
SRC='https://zappysys.com/downloads/files/test/callapi.aspx',
METHOD='POST',
RequestContentTypeCode='ApplicationXml',
BODY='<x><row><name>1.png</name></row><row><name>2.png</name></row><row><name>3.png</name></row></x>',
FILTER='$.x.row[*]',
ALIAS='a',
--Step2: Download files as base64 data for each URL
JOIN1_SRC='https://zappysys.com/images/forums/create-azure-storage-account-get-access-keys-[$a.name$]', --//SRC can be local or URL c:\image.png or http://some/url/file.pdf
JOIN1_SaveContentAsBinary='true', --//This property returns data as base base64 string rather byte array so its easy to pass in next step
JOIN1_METHOD='GET',
JOIN1_ALIAS='b',
--Step3: Upload File - POST File Base64 data to target URL
JOIN2_SRC='https://zappysys.com/downloads/files/test/callapi.aspx',
JOIN2_METHOD='POST',
JOIN2_BODY='<xml><file><name>[$a.name$]</name><base64>[$b.data$]</base64></file></xml>',
JOIN2_ALIAS='c'
)
SELECT * FROM [root.element] WITH
(
SRC='https://zappysys.com/downloads/files/test/cust-1.xml',
EnableStatusCheck='True',
StatucCheckMaxWaitSeconds=7,
StatucCheckIterationWaitSeconds=3,
--StatusCheckForFailedValue = 'True',
--StatusFailedValue = 'Failed|Cancelled',
--StatusFieldFilterExpr='//*[local-name()='Status']', --Use XPath, XmlPath or Regex to narrow down to single property / content under which you like to search
--StatusFieldFilterType='Xml', --or use Xml, Regex, None
StatusSuccessValue='C1|C2|C3' --Wait until C1 or C2 or C3 found in response (Use Regular expression syntax)
)
/*
--- See real world example of status check pattern here (Use of XML Driver)... https://zappysys.com/blog/import-bing-ads-data-sql-server-performance-reports/
SELECT c.* FROM $
WITH(
--///////////////////////////////////
--Step-1: submit report request for XML format
--///////////////////////////////////
alias='a'
,Src='https://reporting.api.bingads.microsoft.com/Api/Advertiser/Reporting/v13/ReportingService.svc'
,Filter='$.s:Envelope.s:Body.SubmitGenerateReportResponse'
,RequestData='@C:\Requests\BingAds\sql_body1.xml' --Get Body from File for clean Look (Read blog post above to see actual body)
,IsMultiPart='True'
,RequestContentTypeCode='TextXml'
,Header='SOAPAction: "SubmitGenerateReport"'
,RequestMethod = 'POST'
,EnableBodyPlaceholderForMultiPart = 'True'
,Meta = '[{ "Name": "ReportRequestId","Type": "Int64"}]'
--///////////////////////////////////
--///Step-2: keep checking status until report is ready - returns final url when done
--///////////////////////////////////
,join1_alias = 'b'
,join1_Filter = '$.s:Envelope.s:Body.PollGenerateReportResponse.ReportRequestStatus'
,join1_RequestData = '@C:\Requests\BingAds\sql_body2.xml'
,join1_IsMultiPart = 'True'
,join1_Src = 'https://reporting.api.bingads.microsoft.com/Api/Advertiser/Reporting/v13/ReportingService.svc'
,join1_RequestContentTypeCode = 'TextXml'
,join1_Header = 'SOAPAction: "PollGenerateReport"'
,join1_RequestMethod = 'POST'
,join1_EnableBodyPlaceholderForMultiPart = 'True'
,join1_EnableStatusCheck = 'True',
,join1_StatucCheckMaxWaitSeconds = 300, --wait max 5 mins ?
,join1_StatucCheckIterationWaitSeconds = 5, --check every 5 sec ?
,join1_StatusSuccessValue = 'Success', --look for success word in response
--, join1_Meta = '[{ "Name": "ReportDownloadUrl","Type": "String",Length: "500"},{ "Name": "Status","Type": "String",Length: "20"}]'
--///////////////////////////////////
--Step-3: Download report(Zip file) and Parse rows
--///////////////////////////////////
,join2_alias = 'c'
,join2_DataConnectionType = 'Default'
,join2_Src = '[$b.ReportDownloadUrl$]'
,join2_Filter = '$.Report.Table.Row[*]'
,join2_ElementsToTreatAsArray = 'Row'
,join2_RequestMethod = 'GET'
,join2_IsMultiPart = 'False'
,join2_FileCompressionType = 'Zip'
)
*/
SELECT * FROM $
WITH(
Src='https://zappysys.com/downloads/files/test/cust-1.xml?really-large-file=1'
,TempStorageMode='Disk' --or 'Memory'
--OR
--,TempStorageMode=1 --//Memory=0, Disk=1
)
SELECT * FROM [data.row]
WITH
(DATA='
<data>
<row><id>1</id><checknumber>0001</checknumber><name>AAA</name></row>
<row><id>2</id><checknumber>0002</checknumber><name>BBB</name></row>
</data>'
--//Method-1: >>>DIRECT META (compact mode)<<<
,META='id:int;checknumber:string(10);name:string(10)'
-- Add: @OverrideMode:1 in the column list to override meta for only specific column(s) - In below example we are changing default datatype/length for id and checknumber, all other columns are dynamic so dont have to supply in META clause
--,META='@OverrideMode:1;id:int;checknumber:string(10)'
--//Method-2: >>>DIRECT META (xml mode)<<<
--,META='[{Name:"id",Type:"Int32"},{Name:"checknumber",Type:"String",Length:10},{Name:"name",Type:"String",Length:10}]'
-- Add: @OverrideMode entry in the column list to override meta for only specific column(s). No need to set Type for that entry - In below example we are changing default datatype/length for id and checknumber, all other columns are dynamic so dont have to supply in META clause
--,META='[{Name:"@OverrideMode"}, {Name:"id",Type:"Int32"},{Name:"checknumber",Type:"String",Length:10}]'
--//Method-3: >>>META from File <<<
--,META='c:\data\meta.xml'
--//Method-4: >>>META from Internal Storage - Just refer entry by name <<<
--,META='MY_META_STORAGE_NAME'
)
SELECT * FROM $
limit 3 WITH
(METHOD='POST' ,HEADER='Content-Type: application/xml || x-hdr1: SomeValue'
,SRC='https://zappysys.com/downloads/files/test/rest-getdata.aspx?postsame=1'
,BODY='
<root>
<row><id>1</id><name>AAA</name></row>
<row><id>2</id><name>BBB</name></row>
</root>'
,Filter='$.root.row[*]')
SELECT * FROM $
WITH (METHOD='POST' ,HEADER='Content-Type: application/xml || x-hdr1: SomeValue'
,SRC='https://zappysys.com/downloads/files/test/rest-getdata.aspx?postsame=1'
,BODY='
<root>
<row><id>1</id><name>AAA</name></row>
<row><id>2</id><name>BBB</name></row>
</root>'
,Filter='$.root.row[*]'
--define output metadata using static value like below or from file
,META='[{Name: "id",Type: "Int32"},{Name: "name",Type: "String",Length: 10}]'
--,META='id=Int32;name=String(10)' --compact meta format
--,META='c:\query_meta.xml'
)
SELECT * FROM $
limit 3 WITH
(METHOD='POST' ,HEADER='Content-Type:text/plain||x-hdr1:AAA'
,SRC='http://httpbin.org/post'
,BODY='@c:\files\dump.xml'
,IsMultiPart='True'
)
exec webRequest 'http://httpbin.org/post', 'POST', '*BODY*', 'x-hdr1: AA||x-hdr2: BB'
--You can also arrange parameters in any order using named parameters and optional parameters
--exec webRequest @verb='POST', @uri='https://httpbin.org/post', @body='*BODY*', @headers='Insecure-Requests: 0||User-Data: httpbin.org'
--exec webRequest @verb='GET', @uri='https://httpbin.org/get'
SELECT
FILE_WRITE_TEXT( RAW_DOCUMENT,'c:\temp\dump.xml' ) AS ColBytesWritten1 --//text file
--,BASE64_TO_FILE('c:\temp\dump.png', FILE_TO_BASE64('http://httpbin.org/image/png') ) AS ColBytesWritten2 --//This is how you can for binary file input must be base64 of data
--,FILE_READ_TEXT('c:\temp\dump.txt' ) DiskFileContent
FROM $
WITH(
Src='https://httpbin.org/xml'
,EnableRawOutputMode='True' --//set this flag to read data as RAW text
)
SELECT
substr('ZappySys', 1, 5)
, printf('%s %s %.2f', 'v1', CompanyName, CompanyId)
, ('Str1' || CompanyName || 'Str2') as ConcatExample
, upper('ZappySys')
, lower('ZappySys')
, replace('ZappySys', 'Sys', 'XYZ')
, instr('ZappySys', 'Sys')
, trim(' Zappy Sys ') trim1
, trim('@@@ZappySys@@@', '@') trim2
, rtrim(' ZappySys ')
, ltrim(' ZappySys ')
, length( CompanyName )
FROM $ WITH (
FILTER='$.Info.Rows[*]',
DATA='
<Info>
<Rows><CompanyId>1000</CompanyId><CompanyName>ZappySys</CompanyName></Rows>
<Rows><CompanyId>1001</CompanyId><CompanyName>Microsoft</CompanyName></Rows>
<Rows><CompanyId>1002</CompanyId><CompanyName>Amazon</CompanyName></Rows>
</Info>
')
SELECT
COALESCE(10,20) coalesce1 --returns first non-null arg
,COALESCE(null,20) coalesce2 --returns first non-null arg
,COALESCE(null,20,30,40) coalesce3 --returns first non-null arg
,IFNULL(null,20) --returns first non-null arg. Same function as COALESCE but simple (just two arguments allowed)
,NULLIF(20,20) nullif1 --returns null if both argument same
,NULLIF(10,20) nullif2 --returns null if both argument same
FROM $ WITH (
FILTER='$.Info.Rows[*]',
DATA='
<Info>
<Rows><CompanyId>1000</CompanyId><CompanyName>ZappySys</CompanyName></Rows>
<Rows><CompanyId>1001</CompanyId><CompanyName>Microsoft</CompanyName></Rows>
</Info>
')
SELECT
DATE('now') date_now
,STRFTIME('%Y-%m-%dT%H:%M:%f','now') formatted_Date_time
,DATETIME('now') datetime_now
,DATE('now','localtime') datetime_now_local
,TIME('now') time_now
,JULIANDAY('now')
,DATE('now', 'start of month', '+1 month' , '-1 day' ) dt_modify1
,DATE('now', '+5 day') dt_modify2
FROM $ WITH (
FILTER='$.Info.Rows[*]',
DATA='
<Info>
<Rows><CompanyId>1000</CompanyId><CompanyName>ZappySys</CompanyName></Rows>
<Rows><CompanyId>1001</CompanyId><CompanyName>Microsoft</CompanyName></Rows>
<Rows><CompanyId>1002</CompanyId><CompanyName>Amazon</CompanyName></Rows>
</Info>
')
SELECT
abs(-500)
,random()
,round(1000.236, 2)
FROM $ WITH (
FILTER='$.Info.Rows[*]',
DATA='
<Info>
<Rows><CompanyId>1000</CompanyId><CompanyName>ZappySys</CompanyName></Rows>
<Rows><CompanyId>1001</CompanyId><CompanyName>Microsoft</CompanyName></Rows>
</Info>
')
SELECT
substr('ZappySys', 1, 5)
, printf('%s %s %.2f', 'v1', CompanyName, CompanyId)
, ('Str1' || CompanyName || 'Str2') as ConcatExample
, upper('ZappySys')
, lower('ZappySys')
, replace('ZappySys', 'Sys', 'XYZ')
, instr('ZappySys', 'Sys')
, trim(' Zappy Sys ') trim1
, trim('@@@ZappySys@@@', '@') trim2
, rtrim(' ZappySys ')
, ltrim(' ZappySys ')
, length( CompanyName )
FROM $ WITH (
FILTER='$.Info.Rows[*]',
DATA='
<Info>
<Rows><CompanyId>1000</CompanyId><CompanyName>ZappySys</CompanyName></Rows>
<Rows><CompanyId>1001</CompanyId><CompanyName>Microsoft</CompanyName></Rows>
<Rows><CompanyId>1002</CompanyId><CompanyName>Amazon</CompanyName></Rows>
</Info>
')
SELECT
regex_ismatch(SSN, '\d{3}-\d{3}-\d{4}') IsValidSSN, --check pattern found
regex_replace(SSN, '\d','*') MaskedSSN, --search/replace pattern
regex_search(SSN, '\d{4}') SSNLast4Digits, --extract substring using pattern search
regex_search(Email, '(?<name>\w+)@(?<domain>\w+.com)',0, 2) DomainOf1stEmailByIndex, --extract 1st email (zero based index) and get domain name (by group name). For 2nd argument you can use numeric index or named argument. Both arguments are zero based index.
regex_search(Email, '(?<name>\w+)@(?<domain>\w+.com)',2, 2) DomainOf3rdEmailByIndex, --extract 3rd email (zero based index) and get 2nd part of match (i.e. domain name). Both arguments are zero based index.
regex_search('a@x.com | b@y.com | c@z.com', '(?<name>\w+)@(?<domain>\w+.com)','-0', 2) DomainOfLastEmail, --extract last email (use negative sign in quote - zero based index) and get 2nd part of match (i.e. domain name). Both arguments are zero based index.
regex_search(
'a@x.com | b@y.com | c@z.com'
, '(?<name>\w+)@(?<domain>\w+.com)'
, '*' --occurrence match index ( * , N or -N ) negative number will do reverse find (e.g. to get last match use -0 , to get second last use -1)
, 2 --group index from match (default is full match or -1)
--, 0 -- ignore case for pattern match (0=strict match, 1=ignore case, default is 0)
--, 0 -- throw error if not matched 0=don't throw error, 1=throw error
--, '#' -- separator for multi match
) GetAllDomains --extract domains from all emails and show as email (zero based index) and get 2nd part of match (i.e. domain name). Both arguments are zero based index.
FROM $ WITH (Filter='$.data.row[*]', DATA= '<data>
<row><SSN>111-222-4444</SSN><Email>a@x.com | b@y.com | c@z.com</Email></row>
<row><SSN>111-X2Z-AB44</SSN><Email>a@x.com | b@y.com | c@z.com</Email></row>
</data>')
SELECT * FROM $ WITH(SRC='http://myservice.com/xml?date-para=<<yyyy-MM-dd,FUN_TODAY>>')
SELECT RTRIM('trimmed ') Col1,
DATE('now', '+5 day') Col2
SELECT * FROM [data.row]
WITH (
--enter path in SRC or use static value in DATA'
--SRC='http://some/api/data.xml'
--SRC='C:\somefile.xml'
--SRC='C:\some*.xml'
DATA='
<data>
<row><_id>1</_id><_name>AAA</_name></row>
<row><_id>2</_id><_name>BBB</_name></row>
</data>'
,ElementsToTreatAsArray='row' --if you don't specify this option then your query may fail when only 1 <row> tag is found (use comma for multiple names e.g. order,item,row).
,EnableCustomReplace=1
,SearchFor='<(/)?_(\w+)>--regex' --//or use --regex-ic (case-insensitive) or no suffix for plain text search.
,ReplaceWith='<$1$2>'
)
SELECT
Pivot_Name as ProjectName,
Pivot_Value_id as Id,
Pivot_Value_code as Code
FROM $
WITH (
Filter='$.data',
--enter path in SRC or use static value in DATA'
--SRC='http://some/api/data.xml'
--SRC='C:\some*.xml'
--SRC='C:\somefile.xml'
DATA='
<data>
<project1><id>1</id><code>AAA</code></project1>
<project2><id>2</id><code>BBB</code></project2>
<project3><id>3</id><code>CCC</code></project3>
</data>',
EnablePivot='True'
)
SELECT * FROM rows
WITH(
--enter path in SRC or use static value in DATA'
--SRC='http://some/api/data.xml'
--SRC='C:\some*.xml'
--SRC='C:\somefile.xml'
DATA='
{
"columns": ["RecordID","CustomerID","CustomerName"],
"rows": [ [1,"AAA","Customer A"], [2,"BBB","Customer B"], [3,"CCC","Customer C"] ]
}'
,ArrayTransformType='TransformSimpleTwoDimensionalArray'
,ArrayTransColumnNameFilter='$.columns[*]'
)
SELECT * FROM rows
WITH(
--enter path in SRC or use static value in DATA'
--SRC='http://some/api/data.xml'
--SRC='C:\some*.xml'
--SRC='C:\somefile.xml'
DATA='
{
"rows": [ [1,"AAA","Customer A"], [2,"BBB","Customer B"], [3,"CCC","Customer C"] ]
}'
,ArrayTransformType='TransformSimpleTwoDimensionalArray'
,ArrayTransEnableCustomColumns='True'
,ArrayTransCustomColumns='RecordID,CustomerID,CustomerName'
)
SELECT * FROM rows
WITH(
--enter path in SRC or use static value in DATA'
--SRC='http://some/api/data.xml'
--SRC='C:\some*.xml'
--SRC='C:\somefile.xml'
DATA='
{
requestid:1,
schema:{ fields:[{name:"id"},{name:"name"},{name:"birthdate"}] },
rows: [ { f:[{v:10},{v:"aaa"},{v:"2015-01-01"}]}, { f:[{v:20},{v:"bbb"},{v:"2015-02-01"}] } ]
}'
,ArrayTransformType = 'TransformComplexTwoDimensionalArray'
,ArrayTransColumnNameFilter = '$.schema.fields[*].name'
,ArrayTransRowValueFilter = '$.f[*].v'
)
SELECT * FROM $
WITH (
--enter path in SRC or use static value in DATA'
--SRC='http://some/api/data.xml'
--SRC='C:\somefile.xml'
--SRC='C:\some*.xml'
DATA='
<data parentCol1="p1" parentCol2="p2">
<row><id>1</id><name>AAA</name></row>
<row><id>2</id><name>BBB</name></row>
</data>'
,Filter='$.data.row[*]' -- for more information check this https://zappysys.com/blog/xmlpath-examples-expression-cheetsheet/
--,Filter='$.data.row[?(@name=='AAA')]' --//equal match example
--,Filter='$..[?(@name=='AAA')]' --//equal match example (scan all levels - parent or child)
--,Filter='$.data.row[?(@name=~/AAA|BBB/)]' --//regex match example
,ElementsToTreatAsArray='row' --if you don't specify this option then your query may fail when only 1 <row> tag is found (use comma for multiple names e.g. order,item,row)
,IncludeParentColumns='true' --this will include any columns found above filtered node (e.g. rows).
,ParentColumnPrefix='p_'
)
SELECT * FROM [root.element] WITH
(
--//separate URLs or Local Paths using double colon ( :: ) or new line (like below).
--//Example of double colon :: as separator
--//http://a.com/storeid=1::http://a.com/storeid=5
SRC='https://zappysys.com/downloads/files/test/cust-1.xml
https://zappysys.com/downloads/files/test/cust-2.xml',
EnableMultiPathMode='True'
)
SELECT * FROM "Root.value"
WHERE OrderDate<=DATETIME('1997-12-31 00:00:00') -- OR use DATE('1997-12-31') DateTime column can be queried this way. You must wrap DATETIME function around it. Also must use 'yyyy-MM-dd' or 'yyyy-MM-dd HH:mm:ss' or 'yyyy-MM-dd HH:mm:ss.fff' format (where fff is milliseconds)
ORDER BY DATETIME(OrderDate)
WITH (SRC='https://zappysys.com/downloads/files/test/invoices.xml')
SELECT
Country AS Invoice_Country
, SUM(UnitPrice * Quantity) AS Invoice_Total
FROM "Root.value"
WHERE Discount > 0
--AND OrderDate<=DATETIME('1997-12-31 00:00:00') -- OR use DATE('1997-12-31') DateTime column can be queried this way. You must wrap DATETIME function around it. Also must use 'yyyy-MM-dd' or 'yyyy-MM-dd HH:mm:ss' or 'yyyy-MM-dd HH:mm:ss.fff' format (where fff is milliseconds)
GROUP BY Country
HAVING SUM(UnitPrice * Quantity) > 1000
ORDER BY Invoice_Total DESC --,DATETIME(OrderDate)
LIMIT 3
WITH (SRC='https://zappysys.com/downloads/files/test/invoices.xml')
SELECT
name
, CASE id
WHEN 1 THEN 1+1
WHEN 2 THEN 2+2
ELSE 0
END ThisIsCaseColumn
FROM [data.row]
WITH (
--enter path in SRC or use static value in DATA'
--SRC='http://some/api/data.xml'
--SRC='C:\some*.xml'
--SRC='C:\somefile.xml'
DATA='
<data>
<row><id>1</id><name>AAA</name></row>
<row><id>2</id><name>BBB</name></row>
</data>'
,ElementsToTreatAsArray='row' --if you don't specify this option then your query may fail when only 1 <row> tag is found (use comma for multiple names e.g. order,item,row).
)
SELECT * INTO #tmp FROM [data.row]
WITH (
--enter path in SRC or use static value in DATA
--SRC='http://some/api/data.xml'
--SRC='C:\some*.xml'
--SRC='C:\somefile.xml'
DATA='
<data>
<row><id>1</id><name>AAA</name></row>
<row><id>2</id><name>BBB</name></row>
<row><id>3</id><name>CCC</name></row>
</data>'
,ElementsToTreatAsArray='row' --if you don't specify this option then your query may fail when only 1 <row> tag is found (use comma for multiple names e.g. order,item,row).
);
--//second statement in the same batch
select * from #tmp
where id > 1
--AND SomeDateColumn=DATETIME('2012-12-31 00:00:00') --DateTime column can be queried this way... Must use 'yyyy-MM-dd HH:mm:ss' format
;
SELECT * INTO #cust FROM [data.row]
WITH (
--enter path in SRC or use static value in DATA
--SRC='http://some/api/customers.xml'
--SRC='C:\cust*.xml'
--SRC='C:\customers.xml'
DATA='
<data>
<row><customerid>1</customerid><name>AAA</name></row>
<row><customerid>2</customerid><name>BBB</name></row>
<row><customerid>3</customerid><name>CCC</name></row>
</data>'
,ElementsToTreatAsArray='row' --if you don't specify this option then your query may fail when only 1 <row> tag is found (use comma for multiple names e.g. order,item,row).
);
SELECT * INTO #ord FROM [data.row]
WITH (
DATA='
<data>
<row><orderid>1000</orderid><customerid>1</customerid><orderdate>2012-01-01T00:00:00</orderdate><total>2000.50</total></row>
<row><orderid>1001</orderid><customerid>1</customerid><orderdate>2012-01-02T00:00:00</orderdate><total>1000.50</total></row>
<row><orderid>1002</orderid><customerid>2</customerid><orderdate>2013-01-01T00:00:00</orderdate><total>5000.70</total></row>
<row><orderid>1003</orderid><customerid>2</customerid><orderdate>2013-01-02T00:00:00</orderdate><total>6000.70</total></row>
</data>'
,ElementsToTreatAsArray='row' --if you don't specify this option then your query may fail when only 1 <row> tag is found (use comma for multiple names e.g. order,item,row).
);
--//second statement in the same batch
SELECT c.customerid,o.orderid,o.orderdate,o.total
FROM #cust c
INNER JOIN #ord o ON c.customerid=o.customerid
--LEFT OUTER JOIN #ord o ON c.customerid=o.customerid
--WHERE o.orderdate='2012-01-01 00:00:00' --for datetime column format must be queried in 'yyyy-MM-dd HH:mm:ss' format only
--To Use greater than less than must need to use DATETIME function (e.g. WHERE o.OrderDate<=DATETIME('1997-12-31 23:12:59')
;
SELECT * into #tbl1 FROM [data.row]
WITH (
--enter path in SRC or use static value in DATA'
--SRC='http://some/api/data.xml'
--SRC='C:\some*.xml'
--SRC='C:\somefile.xml'
DATA='
<data>
<row><id>1</id><name>AAA</name></row>
<row><id>2</id><name>BBB</name></row>
</data>'
,ElementsToTreatAsArray='row' --if you don't specify this option then your query may fail when only 1 <row> tag is found (use comma for multiple names e.g. order,item,row).
);
SELECT * into #tbl2 FROM [data.row]
WITH (
--enter path in SRC or use static value in DATA
--SRC='http://some/api/data.xml'
--SRC='C:\some*.xml'
--SRC='C:\somefile.xml'
DATA='
<data>
<row><id>1</id><name>CCC</name></row>
<row><id>2</id><name>DDD</name></row>
</data>'
,ElementsToTreatAsArray='row' --if you don't specify this option then your query may fail when only 1 <row> tag is found (use comma for multiple names e.g. order,item,row).
);
select * from #tbl1
UNION ALL
select * from #tbl2;
--Whenever Possible try to write Simple Query. When you use WHERE / GROUP BY / ORDER BY Expressions. Driver may invoke Client side processing if server side doesnt support that construct.
--For comment use line comment with two dash (e.g. --my comment) or use block comment for multi line comment (e.g. /*my comment*/ )
--Any query must contain at least two required parts
--data source (or table) names and a list of column names
--column names come first (preceded by SELECT keyword)
--table names follow (preceded by FROM keyword)
--Here is the query that returns all rows with all columns (* stands for all columns) from 'Accounts' table
SELECT * FROM Accounts
--Use quoted identifiers when you have space or other character in names (e.g. Column or Table name contains space)
SELECT ID, "Account Name" FROM "Closed Accounts"
SELECT ID, [Account Name] FROM [Closed Accounts]
--returns all rows from 'Accounts' table, each row will have Id and Amount columns
SELECT Id, Amount FROM Accounts
--returns only those rows of 'Accounts' table that meet next condition: Amount is greater or equal to 1000.0
SELECT Id, Amount FROM Accounts WHERE Amount >= 1000.0
--returns only those rows of 'Accounts' table that meet next condition: Amount is greater than 1000 or DepartamentID is equal to 123
SELECT Id, Amount FROM Accounts WHERE (Amount > 1000.0 OR DepartamentID = 123)
--returns only those rows of 'Accounts' table that meet next condition: DepartamentID is equal to 1, 101 or 202
SELECT Id, Amount FROM Accounts WHERE DepartamentID IN (1, 101, 202)
--returns only those rows of 'Accounts' table that meet next condition: DepartamentID is equal to 321 and Amount is less than 100
SELECT Id, Amount FROM Accounts WHERE DepartamentID = 321 AND Amount < 100
--returns only those rows of 'Persons' table that meet next condition: Name column value starts with 'John'
SELECT * FROM Person WHERE Name LIKE 'John%'
--case statement
SELECT
FirstName,
LastName,
CASE Country
WHEN 'US' THEN 'NA'
WHEN 'Canada' THEN 'NA'
WHEN 'India' THEN 'Asia'
WHEN 'China' THEN 'Asia'
ELSE 'Unknown'
END ColRegion
FROM Person
--escaping string values (use of \n \r \t \v allowed)
SELECT * FROM MyTable WITH( Body=@'Line1\nLine2')