How to take MAX from column values in SparkSQL - sql

I have a use case where I need to take max value from different columns from a table in sparksql.
Below is a sample table -
I want to take the max of values from columns a, b and c without using the union clause.
Below is the SL query I executed -
SELECT (
SELECT MAX(myval)
FROM (VALUES (a),(b),(c)) AS temp(myval)
) AS MaxOfColumns
FROM
table
But this is throwing an error - "cannot evaluate expression outer() in inline table definition; line 3 pos 16"
Could you please help me with this?

array_max
with t(id,a,b,c) as (select stack(2 ,100,1,2,3 ,200,5,6,4))
select *, array_max(array(a,b,c)) as MaxOfColumns
from t
id
a
b
c
MaxOfColumns
100
1
2
3
3
200
5
6
4
6

Related

Snowflake: Repeating rows based on column value

How to repeat rows based on column value in snowflake using sql.
I tried a few methods but not working such as dual and connect by.
I have two columns: Id and Quantity.
For each ID, there are different values of Quantity.
So if you have a count, you can use a generator:
with ten_rows as (
select row_number() over (order by null) as rn
from table(generator(ROWCOUNT=>10))
), data(id, count) as (
select * from values
(1,2),
(2,4)
)
SELECT
d.*
,r.rn
from data as d
join ten_rows as r
on d.count >= r.rn
order by 1,3;
ID
COUNT
RN
1
2
1
1
2
2
2
4
1
2
4
2
2
4
3
2
4
4
Ok let's start by generating some data. We will create 10 rows, with a QTY. The QTY will be randomly chosen as 1 or 2.
Next we want to duplicate the rows with a QTY of 2 and leave the QTY =1 as they are.
Obviously you can change all parameters above to suit your needs - this solution works super fast and in my opinion way better than table generation.
Simply stack SPLIT_TO_TABLE(), REPEAT() with a LATERAL() join and voila.
WITH TEN_ROWS AS (SELECT ROW_NUMBER()OVER(ORDER BY NULL)SOME_ID,UNIFORM(1,2,RANDOM())QTY FROM TABLE(GENERATOR(ROWCOUNT=>10)))
SELECT
TEN_ROWS.*
FROM
TEN_ROWS,LATERAL SPLIT_TO_TABLE(REPEAT('hire me $10/hour',QTY-1),'hire me $10/hour')ALTERNATIVE_APPROACH;

Why does this sql snippet return 8 or 1 always?

What is the result of:
WITH Tbl AS (SELECT 5 AS A UNION SELECT 6 AS A)
SELECT COUNT(*) AS Tbl FROM Tbl AS A, Tbl AS B, Tbl AS C;
I know the result is supposed to be 8 but I don't know why. Also when I change both values (the 5 or 6) to the same thing it returns a table with the value 1 instead of 8 but all other instances it returns 8 no matter what numbers if they are different. I tested it out with an online sql executor.
Here is what the query does:
the common table expression (the subquery within the with clause) generates a derived table made of two rows
then, in the outer query, the from clause generates a cartesian product of this resultset twice: that's a total of 8 rows (2 * 2 * 2)
the select clause counts the number of rows - that's 8
The content of the rows in the with clause does not matter: this 5 and 6 could very well be foo and bar, or null and null, the result would be the same.
What makes a difference is the number of rows that the with clause generates. If it was generating just one row, you would get 1 as a result (1 * 1 * 1). If it was generating 3 rows, you would get 27 - and so on.
This expression:
WITH Tbl AS (SELECT 5 AS A UNION SELECT 6 AS A)
creates a (derived) table with two rows.
This expression:
WITH Tbl AS (SELECT 5 AS A UNION SELECT 5 AS A)
creates a (derived) table with one row, because UNION removes duplicates.
The rest of the query just counts the number of rows in the 3-way Cartesian product, which is either 111 or 222.

SQL Updated question conditional division

Given columns A and B from Table1:
A B
Small 3
Med 4
Med 1
Large 2
Small 1
Given columns S, M, L from Table2:
S M L
5 5 3
8 2 1
4 6 5
2 2 8
I want to create a new column in Table1 that outputs the quotients of values of column B and Avg(Table2.S) only if the entry in the same row in column A of is 'Small'. If column A has 'Med', we divide by Avg(Table2.M) and if it has 'Large', we divide by Avg(Table2.L). It would continue to check this row by row. For example, in the first row of column B, we have '3', and on the same row in column A, we have 'Small', so we would output 0.6316 (3/Avg(Table2.S)). So the expected column, let's call it C, would be:
C
0.6316
1.0667
0.2667
0.4076
0.2105
How would I output C using MS Access SQL? I tried
Select
Switch(Table1.A ='Small', Table1.B/Avg(Table2.S),
Table1.A ='Med', Table1.B/Avg(Table2.M),
Table1.A ='Large', Table1.B/Avg(Table2.L))
From Table1, Table2
but I usually get an error that says my query doesn't include the specified expression as an aggregate function.
Here is a way to do this
select A,B,switch(A="Small",x.avg_s,A="Med",avg_m,A="Large",avg_l) as avg_vals,B/switch(A="Small",x.avg_s,A="Med",avg_m,A="Large",avg_l)
from table1 y,
(select avg(S) as avg_s,avg(M) as avg_m,avg(L) as avg_l
from table2
)x
The output is

columns to rows change in oracle sql

I have columns a,b in table x.And i want to change this columns data into rows.
it is possible to have duplicate vales in table but in columns to row change only distinct values should come.
E.G:
a b
1 2
1 11
3 4
5 6
7 8
9 10
......etc
the result 1 (query 1) should be 1-2,1-11,3-4,5-6,7-8,9-10.....etc
The result 2 (query 2) should b 1,3,5,7,9....etc(only one 1 must come as we have duplicate data for column a)
how can i achieve this in oracle SQL.
Please help.
For Oracle 11 use function listagg() and in first query concatenate columns, in second - select distinct values at first.
Query 1:
select listagg(a||'-'||b, ',') within group (order by a, b) result from t
RESULT
------------------------------
1-2,1-11,3-4,5-6,7-8,9-10
Query 2:
select listagg(a, ',') within group (order by a) result
from (select distinct a from t)
RESULT
------------------------------
1,3,5,7,9
For older versions you can use wmsys.wm_concat.

SQL Query to find which group does not have a given value

I am using T-SQL.
Say if I have the following
Value Nbr
----- ---
one 6
one 7
one 8
two 6
two 7
three 5
three 3
three 2
In the above table, I need to find which group does not have 6 in it.
In this case, it is three as it does not have 6 in it.
What would be the best approach to do this?
I tried:
select Value from tbl1
where nbr <> 6
group by Value
but did not get the intended result.
select distinct value
from tbl1
where value not in
(
select distinct value
from tbl1
where nbr = 6
)