Is it possible to have a WITH-clause inside a SELECT statement? - sql-server-2008

We have a cloud-based GUI at my work where I can choose some fields from different tables so it can print out the values afterwards. It is not possible for me to write a WITH clause before a SELECT statement as the program automatically write SELECT first. So I want to know If it is possible somehow.

Yes you can, according to MSDN documentation (https://msdn.microsoft.com/en-us/library/ms189499.aspx) :
<SELECT statement> ::=
[WITH <common_table_expression> [,...n]]
<query_expression>
[ ORDER BY { order_by_expression | column_position [ ASC | DESC ] }
[ ,...n ] ]
[ <FOR Clause>]
[ OPTION ( <query_hint> [ ,...n ] ) ]
<query_expression> ::=
{ <query_specification> | ( <query_expression> ) }
[ { UNION [ ALL ] | EXCEPT | INTERSECT }
<query_specification> | ( <query_expression> ) [...n ] ]
<query_specification> ::=
SELECT [ ALL | DISTINCT ]
[TOP ( expression ) [PERCENT] [ WITH TIES ] ]
< select_list >
[ INTO new_table ]
[ FROM { <table_source> } [ ,...n ] ]
[ WHERE <search_condition> ]
[ <GROUP BY> ]
[ HAVING < search_condition > ]

If you can't find any other way around it, this GUI might be persuaded to accept
SELECT * FROM (
-- write your entire select statement here
);

Related

How to spare & group objects according key-value

I'm new on this, those are my first steps. I guess I've started with a not simple case.
Let's see:
I have objects, with an ID (name) and a resource group (rgs). Each object may be part of several groups. And what a do need is to get the intersections of the groups.
It is important to say that the object may part of several groups, which are parent-child groups, and I just need to get the parent group. It is easy to identify the parenthoods as they share prefixes.
e.g. Group PROM_FD_ARCNA contains the child groups PROM_FD_ARCNA_TGM and PROM_FD_ARCNA_TGM_TGA.
And the child groups contains the objects itself. But, as long as I can get the information from object, it is over.
The parent groups are PROM_FD_ARCNA, PROM_JOB_ICMP and PROM_JOB_WIN. That is to say, I need to get those objects which belong to the intersections of those groups.
The JSON file which looks like:
[
{
"id_ci": "487006",
"name": "LABTNSARWID625",
"id_ci_class": "host",
"rgs": "PROM_FD_ARCNA, PROM_FD_ARCNA_TGM, PROM_FD_ARCNA_TGM_TGA"
},
{
"id_ci": "5706",
"name": "HCCQ2001",
"id_ci_class": "host",
"rgs": "PROM_JOB_ICMP"
},
{
"id_ci": "9106",
"name": "HCC02155",
"id_ci_class": "host",
"rgs": "PROM_FD_ARCNA, PROM_FD_ARCNA_TGA, PROM_JOB_ICMP"
},
{
"id_ci": "2306",
"name": "VM00006",
"id_ci_class": "host",
"rgs": "PROM_FD_ARCNA, PROM_FD_ARCNA_TGA, PROM_JOB_WIN, PROM_JOB_WIN_TGA"
}
]
If my explanation was not good, I need to get a JSON like this:
PROM_FD_ARCNA, PROM_JOB_ICMP
{
"HCC02155"
}
PROM_FD_ARCNA, PROM_JOB_WIN
{
"VM00006"
}
As those are the intersections.
So far, I tried this:
jq '[.[] | select(.id_ci_class == "host") | select (.rgs | startswith("PROM_FD_ARCNA")) | .rgs = "PROM_FD_ARCNA"]
| group_by(.rgs) | map({"rgs": .[0].rgs, "Hosts": map(.name)}) ' ./prom_jobs.json >> Step0A.json
jq '[.[] | select(.id_ci_class == "host") | select (.rgs | startswith("PROM_JOB_WIN")) | .rgs = "PROM_JOB_WIN"]
| group_by(.rgs) | map({"rgs": .[0].rgs, "Hosts": map(.name)}) ' ./prom_jobs.json >> Step0A.json
jq '[.[] | select(.id_ci_class == "host") | select (.rgs | startswith("PROM_JOB_ICMP")) | .rgs = "PROM_JOB_ICMP"]
| group_by(.rgs) | map({"rgs": .[0].rgs, "Hosts": map(.name)}) ' ./prom_jobs.json >> Step0A.json
And the result is:
[
{
"rgs": "PROM_FD_ARCNA",
"Hosts": [
"LABTNSARWID625",
"HCC02155",
"VM00006"
]
}
]
[
{
"rgs": "PROM_JOB_WIN",
"Hosts": [
"VM00006"
]
}
]
[
{
"rgs": "PROM_JOB_ICMP",
"Hosts": [
"HCCQ2001",
"HCC02155"
]
}
]
Of course, the full JSON is quite long and I need to process this as lightweight as possible. Don't know if I've started well or bad.
def to_set(s): reduce s as $_ ( {}; .[ $_ ] = true );
[ "PROM_FD_ARCNA", "PROM_JOB_ICMP", "PROM_JOB_WIN" ] as $roots |
map(
{
name,
has_rg: to_set( .rgs | split( ", " )[] )
}
) as $hosts |
[
range( 0; $roots | length ) as $i | $roots[ $i ] as $g1 |
range( $i+1; $roots | length ) as $j | $roots[ $j ] as $g2 |
{
root_rgs: [ $g1, $g2 ],
names: [
$hosts[] |
select( .has_rg[ $g1 ] and .has_rg[ $g2 ] ) |
.name
]
} |
select( .names | length > 0 )
]
produces
[
{
"root_rgs": [
"PROM_FD_ARCNA",
"PROM_JOB_ICMP"
],
"names": [
"HCC02155"
]
},
{
"root_rgs": [
"PROM_FD_ARCNA",
"PROM_JOB_WIN"
],
"names": [
"VM00006"
]
}
]
Demo on jqplay

Customize JSON retrieved from mysql

Lets say this is my database table
id ProductID color size
1 abc red L
2 abc green M
3 abc yellow S
4 def purple L
5 def brown M
6 def pink S
Now I am fecthing data using my sql queires but in response i want my json in this structure
{
"status": true,
"message": "All Product Logs has been fetched Successfully",
"products": [
{
"id": "1",
"ProductID": "abc",
"colors": [
"red",
"green",
"yellow",
],
"sizes": [
"L",
"M",
"S",
]
},
{
"id": "2",
"ProductID": "def",
"colors": [
"purple",
"brown",
"pink",
],
"sizes": [
"L",
"M",
"S",
]
}
]
}
And this what i do but it doesn't makes sense
if ($response) {
$JSONDataArray=[];
$ColorDataArray=[];
$SizeDataArray=[];
while($row = mysqli_fetch_array($response)){
$ColorDataArray[]=array($row['color']);
$SizeDataArray[]=array($row['size']);
$JSONDataArray[]=array('productid' =>$row['productid'],'color' => $ColorDataArray,'sizes' => $SizeDataArray);
}
echo json_encode(['status'=>true,'message'=>'All Products has been fetched Successfully','products'=>$JSONDataArray]);
}
Anykind of help would be appreciated. What do u think should i change my database structure or should i change my query. I simply user Select * query without any where clause
One option is to use the JSON_ARRAYAGG function:
SELECT JSON_PRETTY(
CONCAT(
'{"status": true, ',
'"message": "All Product Logs has been fetched Successfully", ',
'"products": [',
(
SELECT
GROUP_CONCAT(`der`.`json`)
FROM (
SELECT
JSON_OBJECT(
'ProductID', `ProductID`,
'colors', JSON_ARRAYAGG(`color`),
'sizes', JSON_ARRAYAGG(`size`)
) `json`
FROM
`tbl`
GROUP BY
`ProductID`
) `der`
),
']}'
)
) `json_response`;
See dbfiddle.
Keep in mind: GROUP_CONCAT: The result is truncated to the maximum length that is given by the group_concat_max_len system variable.

How to flatten json into table

I have just realised on my AWS Aurora postgres cluster having functions with temp_tables are not friendly with read replicas. I need to do a re-write (using CTEs) - anyway.... How do I take a json object with arrays nested and flatten them to a table like so:
{
"data": [
{
"groupName": "TeamA",
"groupCode": "12",
"subGroupCodes": [
"11"
]
},
{
"groupName": "TeamB",
"groupCode": "13",
"subGroupCodes": [
"15", "22"
]
}
]
}
I would like the output table to be:
groupName groupCode subGroupCodes
TeamA 12 11
TeamB 13 15
TeamB 13 22
I know I can get most of the way there with:
SELECT j."groupCode" as int, j."groupName" as pupilgroup_name
FROM json_to_recordset(p_in_filters->'data') j ("groupName" varchar(50), "groupCode" int)
But I just need to get the subGroupCodes as well but unpacking the array and joining to the correct parent groupCodes.
You need to first unnest the array, and then another unnest to get the subgroup codes:
with data (j) as (
values ('{
"data": [
{
"groupName": "TeamA",
"groupCode": "12",
"subGroupCodes": [
"11"
]
},
{
"groupName": "TeamB",
"groupCode": "13",
"subGroupCodes": [
"15", "22"
]
}
]
}'::jsonb)
)
select e ->> 'groupName' as group_name,
e ->> 'groupCode' as code,
sg.*
from data d
cross join lateral jsonb_array_elements(d.j -> 'data') as e(g)
cross join lateral jsonb_array_elements_text(g -> 'subGroupCodes') as sg(subgroup_code)

Reserved keywords after SELECT

Is there a way to know all the possible (acceptable) keywords, after a SELECT statement in SQL before the list of fields?
Edit
Reference DB is MySQL
PostgreSQL 9.4
http://www.postgresql.org/docs/9.4/static/sql-select.html
[ WITH [ RECURSIVE ] with_query [, ...] ]
SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
[ * | expression [ [ AS ] output_name ] [, ...] ]
[ FROM from_item [, ...] ]
[ WHERE condition ]
[ GROUP BY expression [, ...] ]
[ HAVING condition [, ...] ]
[ WINDOW window_name AS ( window_definition ) [, ...] ]
[ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ]
[ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ]
[ LIMIT { count | ALL } ]
[ OFFSET start [ ROW | ROWS ] ]
[ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]
[ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ]
where from_item can be one of:
[ ONLY ] table_name [ * ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
[ LATERAL ] ( select ) [ AS ] alias [ ( column_alias [, ...] ) ]
with_query_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
[ LATERAL ] function_name ( [ argument [, ...] ] )
[ WITH ORDINALITY ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
[ LATERAL ] function_name ( [ argument [, ...] ] ) [ AS ] alias ( column_definition [, ...] )
[ LATERAL ] function_name ( [ argument [, ...] ] ) AS ( column_definition [, ...] )
[ LATERAL ] ROWS FROM( function_name ( [ argument [, ...] ] ) [ AS ( column_definition [, ...] ) ] [, ...] )
[ WITH ORDINALITY ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ]
and with_query is:
with_query_name [ ( column_name [, ...] ) ] AS ( select | values | insert | update | delete )
TABLE [ ONLY ] table_name [ * ]
MySQL 5.6
https://dev.mysql.com/doc/refman/5.6/en/select.html
SELECT
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
select_expr [, select_expr ...]
[FROM table_references
[PARTITION partition_list]
[WHERE where_condition]
[GROUP BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_condition]
[ORDER BY {col_name | expr | position}
[ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[PROCEDURE procedure_name(argument_list)]
[INTO OUTFILE 'file_name'
[CHARACTER SET charset_name]
export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name]]
[FOR UPDATE | LOCK IN SHARE MODE]]
SQL Server 2014
https://msdn.microsoft.com/en-us/library/ms189499.aspx
<SELECT statement> ::=
[ WITH { [ XMLNAMESPACES ,] [ <common_table_expression> [,...n] ] } ]
<query_expression>
[ ORDER BY { order_by_expression | column_position [ ASC | DESC ] }
[ ,...n ] ]
[ <FOR Clause>]
[ OPTION ( <query_hint> [ ,...n ] ) ]
<query_expression> ::=
{ <query_specification> | ( <query_expression> ) }
[ { UNION [ ALL ] | EXCEPT | INTERSECT }
<query_specification> | ( <query_expression> ) [...n ] ]
<query_specification> ::=
SELECT [ ALL | DISTINCT ]
[TOP ( expression ) [PERCENT] [ WITH TIES ] ]
< select_list >
[ INTO new_table ]
[ FROM { <table_source> } [ ,...n ] ]
[ WHERE <search_condition> ]
[ <GROUP BY> ]
[ HAVING < search_condition > ]
See the documentation.
For example: mysql 5.0 documentation
Reserved Keywords in MySql
Keywords are words that have significance in SQL. Certain keywords, such as SELECT, DELETE, or BIGINT, are reserved and require special treatment for use as identifiers such as table and column names. This may also be true for the names of built-in functions.
Nonreserved keywords are permitted as identifiers without quoting. Reserved words are permitted as identifiers if you quote them
Reserved Keywords in MSSQL server :
Microsoft SQL Server uses reserved keywords for defining, manipulating, and accessing databases. Reserved keywords are part of the grammar of the Transact-SQL language that is used by SQL Server to parse and understand Transact-SQL statements and batches.
Although it is syntactically possible to use SQL Server reserved keywords as identifiers and object names in Transact-SQL scripts, you can do this only by using delimited identifiers.

What's the name of this language that describes a language syntax?

for example:
<SELECT statement> ::=
[WITH <common_table_expression> [,...n]]
<query_expression>
[ ORDER BY { order_by_expression | column_position [ ASC | DESC ] }
[ ,...n ] ]
[ COMPUTE
{ { AVG | COUNT | MAX | MIN | SUM } ( expression ) } [ ,...n ]
[ BY expression [ ,...n ] ]
]
[ <FOR Clause>]
[ OPTION ( <query_hint> [ ,...n ] ) ]
<query_expression> ::=
{ <query_specification> | ( <query_expression> ) }
[ { UNION [ ALL ] | EXCEPT | INTERSECT }
<query_specification> | ( <query_expression> ) [...n ] ]
<query_specification> ::=
SELECT [ ALL | DISTINCT ]
[TOP expression [PERCENT] [ WITH TIES ] ]
< select_list >
[ INTO new_table ]
[ FROM { <table_source> } [ ,...n ] ]
[ WHERE <search_condition> ]
[ <GROUP BY> ]
[ HAVING < search_condition > ]
whats the language called?
It's the Backus-Naur Form, actually the Extended Backus-Naur Form.
This is not a language, but a formal description of syntax (in this case for SQL select statements) in BNF (Backus-Naur Form).
Since the example you provide uses "optional" brackets [...] it is actually Extended Backus Naur Form.
That looks a bit like a BNF definition of part of SQL.