Snowflake flatten how to? - snowflake-cloud-data-platform

I have a scenario where data is in below format in SNOWFLAKE SQL. Column AGREEMENTS is framed using listagg
I would like to flatten column "AGREEMENTS" and format the table as below . Requesting help

You'd want to do something along these lines:
SELECT x.{list of fields}, y.value::varchar as agreements
FROM x,
LATERAL FLATTEN(input=>SPLIT(x.agreements,',')) y;

SPLIT_TO_TABLE is the function you are looking for. Given you have so many columns I have not typed them all out. You can use t.* to get them all.
SELECT
t.well,
t.well_co,
<snip>
a.value::text AS agreements,
t.agreements_count
FROM table t,
table(split_to_table(t.agreements, ',') a

Related

Converting two columns table into one column table in Google Sheets

In column A there is a list of tasks.
In column B each task has an associated group.
How to, using built-in formulas, generate sequence like in column D?
Here is a screenshot :
try:
=ARRAYFORMULA(TRIM(TRANSPOSE(SPLIT(QUERY(TRANSPOSE(QUERY(QUERY(IF(A2:B="",,A2:B&"♦"),
"select max(Col1) where Col1 is not null group by Col1 pivot Col2", 0)
,,999^99)),,999^99), "♦"))))
This should work as well as player0s. I keep trying to get him to use FLATTEN() :)
=QUERY(FLATTEN(TRANSPOSE(QUERY(A2:B,"select Max(A) group by A pivot B"))),"where Col1<>''")

SQL How to compare if a variable is the same as a value in a database column?

The problem I have is the following:
I work with a ticket system that uses plugins to realize workflows.
In this case I use SQL to presort incoming emails.
The SQL query looks like this:
SELECT Count(Case when {MSG_CC_002_DeviceReg_MailBody} LIKE '%You have received an invoice from%' Then 1 END);
What I want to do now is instead of using LIKE and then a certain phrase like above, I want to compare this to a column in a database table that contains all necessary phrases.
The table has only two columns, phraseID and phrase.
{MSG_CC_002_DeviceReg_MailBody} is the variable that needs to compared against the values of the column.
So if the variable matches with an entry in the column it should just return 1.
[Edit:]
This is just one of the things I want to use this for, I also have a variable {MSG_CC_002_DeviceReg_MailSender} that will provide the email address that I want to compare to a similar table that contains email addresses.
Is this possible?
If so - how?
You can use join or a subquery:
select count(*)
from t
where exists (select 1
from othertable ot
where {MSG_CC_002_DeviceReg_MailBody} LIKE '%' + ot.phrase + '%'
) ;
This will be dog-slow if you have a lot of phrases or email addresses, but it'll give you what you want.
SELECT COUNT(*) AS RetValue
FROM PhraseTable
WHERE {MSG_CC_002_DeviceReg_MailBody} LIKE '%' + phrase + '%';
Yes it is possible, you can achieve this with using dynamic query. Basically you need to construct your query as a string then execute it.
You can find examples and more information about dynamic query within the following link;
https://www.mssqltips.com/sqlservertip/1160/execute-dynamic-sql-commands-in-sql-server/

Grouping by single column but returning all the columns without including other columns in aggregate function

I am working on an SQL query which should group by a column bidBroker and return all the columns in the table.
I tried it using the following query
select Product,
Term,
BidBroker,
BidVolume,
BidCP,
Bid,
Offer,
OfferCP,
OfferVolume,
OfferBroker,
ProductID,
TermID
from canadiancrudes
group by BidBroker
The above query threw me an error as follows
Column 'canadiancrudes.Product' is invalid in the select list because it is not contained in either an aggregate function or the
GROUP BY clause.
Is there any other way which returns all the data grouping by bidBroker without changing the order of data coming from CanadadianCrudes?
First if you are going to agregate, you should learn about agregate functions.
Then grouping becomes much more obvious.
I think you should explain what you are trying to accomplish here, because I suspect that you are trying to SORT bu Bidbroker, rather than grouping.
If you mean you want to sort by BidBroker, you can use:
SELECT Product,Term,BidBroker,BidVolume,BidCP,Bid,Offer,OfferCP,OfferVolume,OfferBroker,ProductID,TermID
FROM canadiancrudes
ORDER BY BidBroker
If you want to GROUP BY, and give example-data you can use:
SELECT c1.Product,c1.Term,c1.BidBroker,c1.BidVolume,c1.BidCP,c1.Bid,c1.Offer,c1.OfferCP,c1.OfferVolume,c1.OfferBroker,c1.ProductID,c1.TermID
FROM canadiancrudes c1
WHERE c1.YOURPRIMARYKEY IN (
select MIN(c2.YOURPRIMARYKEY) from canadiancrudes c2 group by c2.BidBroker
)
Replace YOURPRIMARYKEY with your column with your row-unique id.
As others have said, don't use "group by" if you don't want to aggregate something. If you do want to aggregate by one column but include others as well, consider researching "partition."

HIVE: GROUP BY doesn't behave as it would in MySQL

I have some experience with MySQL and recently I have to do some work on HIVE instead.
The basic structure of the queries is quite similar between the two, but the GROUP BY in HIVE seems to work a bit differently... Thus I cannot achieve what I could previously achieve in MySQL using GROUP BY.
Following is my question, so say I have a table with column A, B, C, and I want to select the rows with max. B column values grouping by column A. I will do:
SELECT A, max(B) FROM myTable GROUP BY A
The above code would work in HIVE with no problem. But what if I also want to see the value in column C which is in the same row of the row with max. B value? In MySQL I can just do:
SELECT A, max(B), C FROM myTable GROUP BY A
But in HIVE I can't do this. It complains that C is not in the GROUP BY keys, but if I add C into GROUP BY, the result is totally not what I want.
So what is the way to select such desired result in HIVE? Some say using collect_set on column C can solve the problem, but I have no idea how the collect_set is ordered and thus don't know which element to return...
Okay I figured this out... The following would do the trick:
SELECT A, maxB, C FROM myTable JOIN
(SELECT A, max(B) as maxB FROM myTable GROUP BY A) temp
ON myTable.A = temp.A AND myTable.B = temp.maxB
It turns out that I have to write much more code in HIVE to get the same result as I would get with just one line in MySQL... :(
In MySQL you would just get a random C, which is not the one you seem to expect.
See MySQL's SQL_MODE to appropriately let MySQL also refuse such ambiguous code.
(or use MIN(C), to get a specific one)

SQL query join elements

I will re-write my doubt to be more easy to understand.
I have one table named SeqNumbers that have only one column of data named PossibleNumbers, that has value from 1 to 10.000.
Then I have another Table named Terminals and one of the columns have the serial numbers of the terminals. What I want is get all the SerialNumbers that not exists in the Terminals table from 1 to 10.000.
I've created the SeqNumbers table only to do this... maybe there's another solution without using it... that's fine to me.
The query I have is:
SELECT PossibleNumbers from SeqNumbers
Where PossibleNumbers NOT IN (SELECT SerialNumbers from Terminals)**
Basically I want to list ALL serial numbers of terminals that doesn't exists in the database.
This Query works fine I think... but the problem is that I don't want all results in a single column.. I want these results displayed in 4 or 5 columns.
For my purpose I can only use the results from the query like that. I cannot use programmatically methods to do that.
Hope this is more clear now... Thanks for all the help...
select x, x+1000 from tablename
Will that do it for you?
If I'm reading this right, you'd probably have to do a self join; something like:
SELECT
LeftValues.ColA,
RightValues.ColA AS ColB
FROM YourTable LeftValues
LEFT JOIN YourTable RightValues ON LeftValues.ColA = RightValues.ColA - 1000
WHERE LeftValues.ColA < 1000
Note: Use the JOIN that makes sense for you (left if you are willing to accept NULLs in ColB, inner if you only want them where both values exist)
You can use a scripting language to parse the MySQL results to format it anyway you like. Are you using PHP to access the database? If so, let me know and I can cook one up for you.
I just saw your new updated question. In this case the order of the columns will be ordered by your SELECT statement and you can also sort too. Here is an example:
SELECT Column1, Column2 FROM my_table ORDER BY Column1, Column2 ASC

Resources