<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>article Star struct: The secret life of the Asterisk in Technical Blog</title>
    <link>https://community.databricks.com/t5/technical-blog/star-struct-the-secret-life-of-the-asterisk/ba-p/59015</link>
    <description>&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-right" image-alt="star.png" style="width: 200px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/6152i65473B6C7A346588/image-size/small?v=v2&amp;amp;px=200" role="button" title="star.png" alt="star.png" /&gt;&lt;/span&gt;This is an article about a humble and ancient SQL token: The asterisk, aka "star", aka "*". Not to be confused with &lt;A href="https://en.wikipedia.org/wiki/Asterix" target="_self"&gt;Asterix the Gaulle&lt;/A&gt;, for him I recommend a decent bookstore. It's also an article about how I'm humbled by the secrets Spark SQL holds which, after 3 1/2 years at Databricks, I'm still discovering. Unless you are a serious Spark committer, chances are some of what you read here will blow your mind as well as it blew mine.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;H2&gt;The Lone&amp;nbsp;&lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt;&lt;/H2&gt;
&lt;P&gt;We all know and love * (star).&lt;BR /&gt;Star, in its core, is simply a short hand for:&lt;BR /&gt;&lt;FONT face="comic sans ms,sans-serif"&gt;"Insert all columns from all relations in the FROM clause. Do so in the order the relations appear in the syntax, and in the order the columns are appearing in each relation."&lt;/FONT&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT&lt;/FONT&gt; *&lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt; 1,  2,  3&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;c&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;,&lt;BR /&gt;       &lt;FONT color="#008000"&gt;VALUES(&lt;/FONT&gt;10, 20, 30&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;s&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;y&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;z&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt;a  b  c  x  y  z&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-- -- -- -- -- --&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt; 1  2  3 10 20 30&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;You also know that star can be pre-fixed with the name of a relation in the FROM clause.&lt;BR /&gt;In that case it is a short hand for:&lt;BR /&gt;&lt;FONT face="comic sans ms,sans-serif"&gt;"Insert all columns of this relation in the order they appear."&lt;/FONT&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT *&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#008000"&gt;  FROM VALUES(&lt;/FONT&gt; 1,  2,  3&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;c&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;,&lt;BR /&gt;       &lt;FONT color="#008000"&gt;VALUES(&lt;/FONT&gt;10, 20, 30)&lt;FONT color="#008000"&gt; AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;s&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;y&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;z&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt; x  y  z&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-- -- --&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;10 20 30&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;Star does not need to be the sole entry in the SELECT list. You can add additional expressions and multiple stars.&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT *&lt;/FONT&gt;, 'Hello' &lt;FONT color="#008000"&gt;AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;hello&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;.*, &lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt; + &lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt; &lt;FONT color="#008000"&gt;AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;ax&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;s&lt;/FONT&gt;.&lt;FONT color="#008000"&gt;*&lt;/FONT&gt; &lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt; 1,  2,  3&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;c&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;,&lt;BR /&gt;       &lt;FONT color="#008000"&gt;VALUES(&lt;/FONT&gt;10, 20, 30&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;s&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;y&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;z&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt; a  b  c  x  y  z hello  a  b ax  x  y  z&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-- -- -- -- -- -- ----- -- -- -- -- -- --&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt; 1  2  3 10 20 30 Hello  1  b 11 10 20 30&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;So far so good. This is the baseline which most products support. Star can also be used with count(*), but that's besides the point.&lt;/P&gt;
&lt;H2&gt;The EXCEPTional &lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt;&lt;/H2&gt;
&lt;P&gt;"All columns" is such an absolutist thing to say. Clearly, if you just want a "few" columns you can just specify them. But you want "most" or "nearly all" columns (like my son who, with surgical precision, works around the food on the plate he does not like to claim he ate nearly all of it and can be dismissed from the table).&lt;BR /&gt;For this purpose Databricks introduced the EXCEPT clause. It works as you expect:&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT * EXCEPT (&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;y&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;&lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt; 1,  2,  3&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;c&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;,&lt;BR /&gt;       &lt;FONT color="#008000"&gt;VALUES(&lt;/FONT&gt;10, 20, 30&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;s&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;y&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;z&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt; a  c  x  z&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-- -- -- --&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt; 1  3 10 30&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;EXCEPT does have another trick up its sleeve though. It can, with surgical precision matching that of my son's, carve out fields it distastes from a struct:&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT * EXCEPT (&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;d&lt;/FONT&gt;.&lt;FONT color="#FF9900"&gt;y&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;&lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt;1, 2, 3, named_struct&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;'x', 10, 'y', 20, 'z', 30&lt;FONT color="#008000"&gt;)) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;(&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;c&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;d&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt; a  c             d&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-- -- -------------&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt; 1  3 {x: 10 y: 30}&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;This much you may know as a user of Databricks who reads the SQL Reference (Hey, I can dream, can I not?) or at least follows the release notes.&lt;BR /&gt;&lt;BR /&gt;But now we're going to enter previously uncharted territory. Uncharted because at least I did not even know that I did not know.&lt;/P&gt;
&lt;H2&gt;&lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt; STRUCT Episode 1&lt;/H2&gt;
&lt;P&gt;At the beginning of this blog I noted that you can limit the star to a specific table in the FROM column by prefixing it with a relation name.&lt;BR /&gt;What if I tell you that you can also prefix it with a column or (hang on to your seat!) a field name?&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT * EXCEPT (&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;d&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;d&lt;/FONT&gt;.&lt;FONT color="#008000"&gt;* EXCEPT(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;y&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;&lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt; 1, 2, 3, named_struct&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;'x', 10, 'y', 20, 'z', 30&lt;FONT color="#008000"&gt;)) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;(&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;c&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;d&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt; a  b  c  x  z&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-- -- -- -- --&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt; 1  2  3 10 30&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;As you can see you can very easily flatten a struct. And it is fully composable with EXCEPT and regular star usage.&lt;/P&gt;
&lt;P&gt;Dare we dream? Here it comes...&lt;/P&gt;
&lt;H2&gt;&lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt; STRUCT Episode 2&lt;/H2&gt;
&lt;P&gt;You can actually nest star inside of the struct function. Databricks will expand all columns as arguments to the struct function and struct will pick up the column names as field names:&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, struct&lt;FONT color="#008000"&gt;(* EXCEPT (&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;struct&lt;/FONT&gt;&lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt;1, 2, 3&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;c&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt; a       struct&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-- ------------&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt; 1 {b: 2, c: 3}&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;Now that's what I call cool! But is it the best star has to offer? Not by a long shot.&lt;/P&gt;
&lt;H2&gt;ARRAYsing &lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt;&lt;/H2&gt;
&lt;P&gt;If you think turning columns into struct with a few keystrokes is nice, how about turning column values into an array?&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, array&lt;FONT color="#008000"&gt;(* EXCEPT (&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;)&lt;/FONT&gt;&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;array&lt;/FONT&gt;&lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt;1, 2, 3&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;c&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt; a  array&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-- ------&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#FF9900"&gt;&lt;FONT color="#993366"&gt; 1 [2, 3]&lt;/FONT&gt;&lt;BR /&gt;&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;So, are ARRAy and STRUCT special in their support for star, just like COUNT(*)?&lt;/P&gt;
&lt;H2&gt;The GREATEST &lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt; and many more&lt;/H2&gt;
&lt;P&gt;It turns out you can use star on any function. The function will simply accept the columns expanded by star as as arguments and do what it always does. Naturally the most interesting applications are those of functions with variable number of arguments, such as:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;GREATEST&lt;/LI&gt;
&lt;LI&gt;LEAST&lt;/LI&gt;
&lt;LI&gt;COALESCE&lt;/LI&gt;
&lt;LI&gt;CONCAT&lt;/LI&gt;
&lt;LI&gt;CONCAT_WS&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Here we turn all columns into a comma separated string:&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT&lt;/FONT&gt; concat_ws&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;', ', &lt;FONT color="#008000"&gt;*)&lt;/FONT&gt; &lt;FONT color="#008000"&gt;AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;result&lt;/FONT&gt;&lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt;1, 2, 3&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;c&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt; result&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-------&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;1, 2, 3&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;It doesn't matter where the star is, as long as it is within the SELECT list.&lt;/P&gt;
&lt;H2&gt;&lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt; MAP?&lt;/H2&gt;
&lt;P&gt;While you can use * on MAP, it is a function after all, MAP takes key value pairs, unlike STRUCT it does not derive keys from the column names.&lt;BR /&gt;So you can do:&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT&lt;/FONT&gt; map&lt;FONT color="#008000"&gt;(*) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;result&lt;/FONT&gt;&lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt;'a', 1, 'b', 2, 'c', 3&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;(&lt;FONT color="#FF9900"&gt;key1&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;val1&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;key2&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;val2&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;key3&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;val3&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt;            result&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;------------------&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;{a-&amp;gt;1, b-&amp;gt;2, c-&amp;gt;3} &lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;But this isn't really that useful.&lt;/P&gt;
&lt;P&gt;One option I see in the future is:&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt; map ( structExpr )&lt;/PRE&gt;
&lt;P&gt;which turns a struct into map.&lt;/P&gt;
&lt;H2&gt;CoLATERAL &lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt;&lt;/H2&gt;
&lt;P&gt;At the very beginning I state that star covers all the columns in all the relations in the FROM clause.&lt;BR /&gt;This is true for the unqualified star:&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;.&lt;FONT color="#008000"&gt;*&lt;/FONT&gt;&lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt;1, 2&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;,&lt;BR /&gt;       &lt;FONT color="#008000"&gt;LATERAL(SELECT&lt;/FONT&gt; &lt;FONT color="#008000"&gt;*&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#008000"&gt;                 FROM VALUES(&lt;/FONT&gt;10, 20&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;s&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;y&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt; x  y&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-- --&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;10 20 &lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;But we can actually explicitly refer to a LATERAL relation using star:&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;.&lt;FONT color="#008000"&gt;*&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#008000"&gt;  FROM VALUES(&lt;/FONT&gt;1, 2&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; t&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;a, b&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;,&lt;BR /&gt;       &lt;FONT color="#008000"&gt;LATERAL(SELECT&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;.&lt;FONT color="#008000"&gt;*&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#008000"&gt;                 FROM VALUES(&lt;/FONT&gt;10, 20&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;s&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;y&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#FF9900"&gt; a  b&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#FF9900"&gt;-- --&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#FF9900"&gt; 1  2&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;That's interesting in the abstract, but it opens the door for future exploitation.&lt;/P&gt;
&lt;H2&gt;To the &lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt; and Beyond&lt;/H2&gt;
&lt;P&gt;There are more possible futures for the usage of star:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Some vendors, including Spark, have started experimenting with regular expression matching.&lt;/LI&gt;
&lt;LI&gt;There is no reason to limit star to the SELECT clause. E,g. WHERE ? IN (*) could be fun.&lt;/LI&gt;
&lt;LI&gt;LATERAL Star on varg style table functions could be interesting.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Conclusion: &lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt;&lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt;&lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt;&lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt;&lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt; for &lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt;&lt;/H2&gt;
&lt;P&gt;I hope you had fun discovering what lies beyond the simple Star with me.&lt;BR /&gt;It makes me wonder what other easter eggs are hidden in Spark that I have yet to discover.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;References:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="https://docs.databricks.com/en/sql/language-manual/sql-ref-syntax-qry-select-table-reference.html" target="_self"&gt;LATERAL correlation&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://docs.databricks.com/en/sql/language-manual/sql-ref-syntax-qry-star.html" target="_self"&gt;Star clause&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://docs.databricks.com/en/sql/language-manual/sql-ref-function-invocation.html" target="_self"&gt;Function invocation&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
    <pubDate>Thu, 08 Feb 2024 22:41:11 GMT</pubDate>
    <dc:creator>SergeRielau</dc:creator>
    <dc:date>2024-02-08T22:41:11Z</dc:date>
    <item>
      <title>Star struct: The secret life of the Asterisk</title>
      <link>https://community.databricks.com/t5/technical-blog/star-struct-the-secret-life-of-the-asterisk/ba-p/59015</link>
      <description>&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-right" image-alt="star.png" style="width: 200px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/6152i65473B6C7A346588/image-size/small?v=v2&amp;amp;px=200" role="button" title="star.png" alt="star.png" /&gt;&lt;/span&gt;This is an article about a humble and ancient SQL token: The asterisk, aka "star", aka "*". Not to be confused with &lt;A href="https://en.wikipedia.org/wiki/Asterix" target="_self"&gt;Asterix the Gaulle&lt;/A&gt;, for him I recommend a decent bookstore. It's also an article about how I'm humbled by the secrets Spark SQL holds which, after 3 1/2 years at Databricks, I'm still discovering. Unless you are a serious Spark committer, chances are some of what you read here will blow your mind as well as it blew mine.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;H2&gt;The Lone&amp;nbsp;&lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt;&lt;/H2&gt;
&lt;P&gt;We all know and love * (star).&lt;BR /&gt;Star, in its core, is simply a short hand for:&lt;BR /&gt;&lt;FONT face="comic sans ms,sans-serif"&gt;"Insert all columns from all relations in the FROM clause. Do so in the order the relations appear in the syntax, and in the order the columns are appearing in each relation."&lt;/FONT&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT&lt;/FONT&gt; *&lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt; 1,  2,  3&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;c&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;,&lt;BR /&gt;       &lt;FONT color="#008000"&gt;VALUES(&lt;/FONT&gt;10, 20, 30&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;s&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;y&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;z&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt;a  b  c  x  y  z&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-- -- -- -- -- --&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt; 1  2  3 10 20 30&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;You also know that star can be pre-fixed with the name of a relation in the FROM clause.&lt;BR /&gt;In that case it is a short hand for:&lt;BR /&gt;&lt;FONT face="comic sans ms,sans-serif"&gt;"Insert all columns of this relation in the order they appear."&lt;/FONT&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT *&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#008000"&gt;  FROM VALUES(&lt;/FONT&gt; 1,  2,  3&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;c&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;,&lt;BR /&gt;       &lt;FONT color="#008000"&gt;VALUES(&lt;/FONT&gt;10, 20, 30)&lt;FONT color="#008000"&gt; AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;s&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;y&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;z&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt; x  y  z&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-- -- --&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;10 20 30&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;Star does not need to be the sole entry in the SELECT list. You can add additional expressions and multiple stars.&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT *&lt;/FONT&gt;, 'Hello' &lt;FONT color="#008000"&gt;AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;hello&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;.*, &lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt; + &lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt; &lt;FONT color="#008000"&gt;AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;ax&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;s&lt;/FONT&gt;.&lt;FONT color="#008000"&gt;*&lt;/FONT&gt; &lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt; 1,  2,  3&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;c&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;,&lt;BR /&gt;       &lt;FONT color="#008000"&gt;VALUES(&lt;/FONT&gt;10, 20, 30&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;s&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;y&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;z&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt; a  b  c  x  y  z hello  a  b ax  x  y  z&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-- -- -- -- -- -- ----- -- -- -- -- -- --&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt; 1  2  3 10 20 30 Hello  1  b 11 10 20 30&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;So far so good. This is the baseline which most products support. Star can also be used with count(*), but that's besides the point.&lt;/P&gt;
&lt;H2&gt;The EXCEPTional &lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt;&lt;/H2&gt;
&lt;P&gt;"All columns" is such an absolutist thing to say. Clearly, if you just want a "few" columns you can just specify them. But you want "most" or "nearly all" columns (like my son who, with surgical precision, works around the food on the plate he does not like to claim he ate nearly all of it and can be dismissed from the table).&lt;BR /&gt;For this purpose Databricks introduced the EXCEPT clause. It works as you expect:&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT * EXCEPT (&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;y&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;&lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt; 1,  2,  3&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;c&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;,&lt;BR /&gt;       &lt;FONT color="#008000"&gt;VALUES(&lt;/FONT&gt;10, 20, 30&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;s&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;y&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;z&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt; a  c  x  z&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-- -- -- --&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt; 1  3 10 30&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;EXCEPT does have another trick up its sleeve though. It can, with surgical precision matching that of my son's, carve out fields it distastes from a struct:&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT * EXCEPT (&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;d&lt;/FONT&gt;.&lt;FONT color="#FF9900"&gt;y&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;&lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt;1, 2, 3, named_struct&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;'x', 10, 'y', 20, 'z', 30&lt;FONT color="#008000"&gt;)) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;(&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;c&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;d&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt; a  c             d&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-- -- -------------&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt; 1  3 {x: 10 y: 30}&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;This much you may know as a user of Databricks who reads the SQL Reference (Hey, I can dream, can I not?) or at least follows the release notes.&lt;BR /&gt;&lt;BR /&gt;But now we're going to enter previously uncharted territory. Uncharted because at least I did not even know that I did not know.&lt;/P&gt;
&lt;H2&gt;&lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt; STRUCT Episode 1&lt;/H2&gt;
&lt;P&gt;At the beginning of this blog I noted that you can limit the star to a specific table in the FROM column by prefixing it with a relation name.&lt;BR /&gt;What if I tell you that you can also prefix it with a column or (hang on to your seat!) a field name?&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT * EXCEPT (&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;d&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;d&lt;/FONT&gt;.&lt;FONT color="#008000"&gt;* EXCEPT(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;y&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;&lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt; 1, 2, 3, named_struct&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;'x', 10, 'y', 20, 'z', 30&lt;FONT color="#008000"&gt;)) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;(&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;c&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;d&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt; a  b  c  x  z&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-- -- -- -- --&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt; 1  2  3 10 30&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;As you can see you can very easily flatten a struct. And it is fully composable with EXCEPT and regular star usage.&lt;/P&gt;
&lt;P&gt;Dare we dream? Here it comes...&lt;/P&gt;
&lt;H2&gt;&lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt; STRUCT Episode 2&lt;/H2&gt;
&lt;P&gt;You can actually nest star inside of the struct function. Databricks will expand all columns as arguments to the struct function and struct will pick up the column names as field names:&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, struct&lt;FONT color="#008000"&gt;(* EXCEPT (&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;struct&lt;/FONT&gt;&lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt;1, 2, 3&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;c&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt; a       struct&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-- ------------&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt; 1 {b: 2, c: 3}&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;Now that's what I call cool! But is it the best star has to offer? Not by a long shot.&lt;/P&gt;
&lt;H2&gt;ARRAYsing &lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt;&lt;/H2&gt;
&lt;P&gt;If you think turning columns into struct with a few keystrokes is nice, how about turning column values into an array?&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, array&lt;FONT color="#008000"&gt;(* EXCEPT (&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;)&lt;/FONT&gt;&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;array&lt;/FONT&gt;&lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt;1, 2, 3&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;c&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt; a  array&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-- ------&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#FF9900"&gt;&lt;FONT color="#993366"&gt; 1 [2, 3]&lt;/FONT&gt;&lt;BR /&gt;&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;So, are ARRAy and STRUCT special in their support for star, just like COUNT(*)?&lt;/P&gt;
&lt;H2&gt;The GREATEST &lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt; and many more&lt;/H2&gt;
&lt;P&gt;It turns out you can use star on any function. The function will simply accept the columns expanded by star as as arguments and do what it always does. Naturally the most interesting applications are those of functions with variable number of arguments, such as:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;GREATEST&lt;/LI&gt;
&lt;LI&gt;LEAST&lt;/LI&gt;
&lt;LI&gt;COALESCE&lt;/LI&gt;
&lt;LI&gt;CONCAT&lt;/LI&gt;
&lt;LI&gt;CONCAT_WS&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Here we turn all columns into a comma separated string:&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT&lt;/FONT&gt; concat_ws&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;', ', &lt;FONT color="#008000"&gt;*)&lt;/FONT&gt; &lt;FONT color="#008000"&gt;AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;result&lt;/FONT&gt;&lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt;1, 2, 3&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;c&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt; result&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-------&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;1, 2, 3&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;It doesn't matter where the star is, as long as it is within the SELECT list.&lt;/P&gt;
&lt;H2&gt;&lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt; MAP?&lt;/H2&gt;
&lt;P&gt;While you can use * on MAP, it is a function after all, MAP takes key value pairs, unlike STRUCT it does not derive keys from the column names.&lt;BR /&gt;So you can do:&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT&lt;/FONT&gt; map&lt;FONT color="#008000"&gt;(*) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;result&lt;/FONT&gt;&lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt;'a', 1, 'b', 2, 'c', 3&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;(&lt;FONT color="#FF9900"&gt;key1&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;val1&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;key2&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;val2&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;key3&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;val3&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt;            result&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;------------------&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;{a-&amp;gt;1, b-&amp;gt;2, c-&amp;gt;3} &lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;But this isn't really that useful.&lt;/P&gt;
&lt;P&gt;One option I see in the future is:&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt; map ( structExpr )&lt;/PRE&gt;
&lt;P&gt;which turns a struct into map.&lt;/P&gt;
&lt;H2&gt;CoLATERAL &lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt;&lt;/H2&gt;
&lt;P&gt;At the very beginning I state that star covers all the columns in all the relations in the FROM clause.&lt;BR /&gt;This is true for the unqualified star:&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;.&lt;FONT color="#008000"&gt;*&lt;/FONT&gt;&lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt;1, 2&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;,&lt;BR /&gt;       &lt;FONT color="#008000"&gt;LATERAL(SELECT&lt;/FONT&gt; &lt;FONT color="#008000"&gt;*&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#008000"&gt;                 FROM VALUES(&lt;/FONT&gt;10, 20&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;s&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;y&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt; x  y&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-- --&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;10 20 &lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;But we can actually explicitly refer to a LATERAL relation using star:&lt;/P&gt;
&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;.&lt;FONT color="#008000"&gt;*&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#008000"&gt;  FROM VALUES(&lt;/FONT&gt;1, 2&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; t&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;a, b&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;,&lt;BR /&gt;       &lt;FONT color="#008000"&gt;LATERAL(SELECT&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;.&lt;FONT color="#008000"&gt;*&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#008000"&gt;                 FROM VALUES(&lt;/FONT&gt;10, 20&lt;FONT color="#008000"&gt;) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;s&lt;/FONT&gt;&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;y&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;x&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#FF9900"&gt; a  b&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#FF9900"&gt;-- --&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#FF9900"&gt; 1  2&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;That's interesting in the abstract, but it opens the door for future exploitation.&lt;/P&gt;
&lt;H2&gt;To the &lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt; and Beyond&lt;/H2&gt;
&lt;P&gt;There are more possible futures for the usage of star:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Some vendors, including Spark, have started experimenting with regular expression matching.&lt;/LI&gt;
&lt;LI&gt;There is no reason to limit star to the SELECT clause. E,g. WHERE ? IN (*) could be fun.&lt;/LI&gt;
&lt;LI&gt;LATERAL Star on varg style table functions could be interesting.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Conclusion: &lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt;&lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt;&lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt;&lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt;&lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt; for &lt;span class="lia-unicode-emoji" title=":star:"&gt;⭐&lt;/span&gt;&lt;/H2&gt;
&lt;P&gt;I hope you had fun discovering what lies beyond the simple Star with me.&lt;BR /&gt;It makes me wonder what other easter eggs are hidden in Spark that I have yet to discover.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;References:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="https://docs.databricks.com/en/sql/language-manual/sql-ref-syntax-qry-select-table-reference.html" target="_self"&gt;LATERAL correlation&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://docs.databricks.com/en/sql/language-manual/sql-ref-syntax-qry-star.html" target="_self"&gt;Star clause&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://docs.databricks.com/en/sql/language-manual/sql-ref-function-invocation.html" target="_self"&gt;Function invocation&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Thu, 08 Feb 2024 22:41:11 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/star-struct-the-secret-life-of-the-asterisk/ba-p/59015</guid>
      <dc:creator>SergeRielau</dc:creator>
      <dc:date>2024-02-08T22:41:11Z</dc:date>
    </item>
    <item>
      <title>Re: Star struct: The secret life of the Asterisk</title>
      <link>https://community.databricks.com/t5/technical-blog/star-struct-the-secret-life-of-the-asterisk/bc-p/59730#M112</link>
      <description>&lt;P&gt;Great info!&lt;BR /&gt;I'll have to try those at work!&lt;BR /&gt;&lt;BR /&gt;Just a very humble and simple observation: this (great) article would greatly benefit from using a simple example table, instead of A, B, C, 1, 2, 3.&lt;BR /&gt;I'm sure I'm not the only average SQL user who can't really follow the examples provided.&lt;/P&gt;</description>
      <pubDate>Thu, 08 Feb 2024 23:56:31 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/star-struct-the-secret-life-of-the-asterisk/bc-p/59730#M112</guid>
      <dc:creator>glater</dc:creator>
      <dc:date>2024-02-08T23:56:31Z</dc:date>
    </item>
    <item>
      <title>Re: Star struct: The secret life of the Asterisk</title>
      <link>https://community.databricks.com/t5/technical-blog/star-struct-the-secret-life-of-the-asterisk/bc-p/59731#M113</link>
      <description>&lt;P&gt;&lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/99551"&gt;@glater&lt;/a&gt;&amp;nbsp;Thanks, I have to fix a couple of typos. Perhaps I can improve the examples along the way.&lt;BR /&gt;But definitely good, and much appreciated advise moving forward.&lt;/P&gt;</description>
      <pubDate>Thu, 08 Feb 2024 23:59:20 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/star-struct-the-secret-life-of-the-asterisk/bc-p/59731#M113</guid>
      <dc:creator>SergeRielau</dc:creator>
      <dc:date>2024-02-08T23:59:20Z</dc:date>
    </item>
    <item>
      <title>Re: Star struct: The secret life of the Asterisk</title>
      <link>https://community.databricks.com/t5/technical-blog/star-struct-the-secret-life-of-the-asterisk/bc-p/59755#M114</link>
      <description>&lt;P&gt;Great feature!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;FONT color="#008000"&gt;SELECT * EXCEPT (&lt;/FONT&gt;&lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;d&lt;/FONT&gt;.&lt;FONT color="#FF9900"&gt;y&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;&lt;BR /&gt;  &lt;FONT color="#008000"&gt;FROM VALUES(&lt;/FONT&gt;1, 2, 3, named_struct&lt;FONT color="#008000"&gt;(&lt;/FONT&gt;'x', 10, 'y', 20, 'z', 30&lt;FONT color="#008000"&gt;)) AS&lt;/FONT&gt; &lt;FONT color="#FF9900"&gt;t&lt;/FONT&gt;(&lt;FONT color="#FF9900"&gt;a&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;b&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;c&lt;/FONT&gt;, &lt;FONT color="#FF9900"&gt;d&lt;/FONT&gt;&lt;FONT color="#008000"&gt;)&lt;/FONT&gt;;&lt;BR /&gt;&lt;FONT color="#993366"&gt; a  c             d&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt;-- -- -------------&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#993366"&gt; 1  3 {x: 10 y: 30}&lt;/FONT&gt;&lt;/PRE&gt;&lt;P&gt;d in the output should be "{x: 10 z: 30}".&lt;/P&gt;</description>
      <pubDate>Fri, 09 Feb 2024 06:27:58 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/star-struct-the-secret-life-of-the-asterisk/bc-p/59755#M114</guid>
      <dc:creator>zshao</dc:creator>
      <dc:date>2024-02-09T06:27:58Z</dc:date>
    </item>
    <item>
      <title>Re: Star struct: The secret life of the Asterisk</title>
      <link>https://community.databricks.com/t5/technical-blog/star-struct-the-secret-life-of-the-asterisk/bc-p/60276#M121</link>
      <description>&lt;P&gt;&lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/99559"&gt;@zshao&lt;/a&gt;&amp;nbsp;Thanks. I'm working on fixing typos, providing a notebook and generally making the examples more useful.&lt;/P&gt;</description>
      <pubDate>Thu, 15 Feb 2024 00:02:04 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/star-struct-the-secret-life-of-the-asterisk/bc-p/60276#M121</guid>
      <dc:creator>SergeRielau</dc:creator>
      <dc:date>2024-02-15T00:02:04Z</dc:date>
    </item>
  </channel>
</rss>

