snowflake - select all columns without writing out each column and unnest one - snowflake-cloud-data-platform

Hello I need to create a new table, from another table that has a nested column (EX: metrics col.) that I need to unnest for the new table without writing out each column (because.. what if I have 100 columns):
INSERT INTO new_table
SELECT sales_uk, sales_ca, sales_sp, sales_us, sales, metrics[0]:category::string FROM og_table
is there another way? I've tried this but it didn't work:
select io.metrics[0]:category::string as new_id, io.*
from og_table io

If I understand your question correctly (that you have a variant column which you want to structure into a column for every object key) and it is acceptable to use copy/paste, then there should be an acceptable approach like this using lateral flatten of the variant column to produce a list of copy/paste-able columns for your new table definition.
with og as (select array_construct(object_construct(
'category', 1,
'bar', 2,
'baz', 3
)) metrics)
select 'metrics'||metrics_array.path||':'||metrics_object.path||'::string as '||metrics_object.path||',' newcol from og
,lateral flatten(metrics) metrics_array
,lateral flatten(metrics_array.value) metrics_object;
--Produces output like:
metrics[0]:bar::string as bar,
metrics[0]:baz::string as baz,
metrics[0]:category::string as category,

Related

Can you insert or update a row based on multiple values being identical in SQLite?

I'm not very experienced with SQLite, and I want to perform some operations based on a local database. My data consists of a lot of entries of one ID, and there are some additional IDs to specify the data. Based on multiple IDs, there should be a unique combination for each entry in the table.
I would like to select (if it exists) a row based on a combination of IDs, and either insert or update some columns in that row.
I haven't really tried anything because I can't find where to start.
But to illustrate what I mean, I would think of something like this:
UPDATE OR REPLACE INTO my_table (ID,Part_ID,Location_ID,Torque) VALUES (2,6,4,100) WHERE (ID,Part_ID,Location_ID) = (2,6,4)
First, you need a unique constraint for the combination of the columns ID, Part_ID and Location_ID, which you can define with a unique index:
CREATE UNIQUE INDEX idx_my_table ON my_table (ID, Part_ID, Location_ID);
Then use UPSERT:
INSERT INTO my_table (ID, Part_ID, Location_ID, Torque) VALUES (2, 6, 4, 100)
ON CONFLICT(ID, Part_ID, Location_ID) DO UPDATE
SET Torque = EXCLUDED.Torque;
See the demo.

Need to Add Values to Certain Items

I have a table that I need to add the same values to a whole bunch of items
(in a nut shell if the item doesn't have a UNIT of "CTN" I want to add the same values i have listed to them all)
I thought the following would work but it doesn't :(
Any idea what i am doing wrong ?
INSERT INTO ICUNIT
(UNIT,AUDTDATE,AUDTTIME,AUDTUSER,AUDTORG,CONVERSION)
VALUES ('CTN','20220509','22513927','ADMIN','AU','1')
WHERE ITEMNO In '0','etc','etc','etc'
If I understand correctly you might want to use INSERT INTO ... SELECT from original table with your condition.
INSERT INTO ICUNIT (UNIT,AUDTDATE,AUDTTIME,AUDTUSER,AUDTORG,CONVERSION)
SELECT 'CTN','20220509','22513927','ADMIN','AU','1'
FROM ICUNIT
WHERE ITEMNO In ('0','etc','etc','etc')
The query you needs starts by selecting the filtered items. So it seems something like below is your starting point
select <?> from dbo.ICUNIT as icu where icu.UNIT <> 'CTN' order by ...;
Notice the use of schema name, terminators, and table aliases - all best practices. I will guess that a given "item" can have multiple rows in this table so long as ICUNIT is unique within ITEMNO. Correct? If so, the above query won't work. So let's try slightly more complicated filtering.
select distinct icu.ITEMNO
from dbo.ICUNIT as icu
where not exists (select * from dbo.ICUNIT as ctns
where ctns.ITEMNO = icu.ITEMNO -- correlating the subquery
and ctns.UNIT = 'CTN')
order by ...;
There are other ways to do that above but that is one common way. That query will produce a resultset of all ITEMNO values in your table that do not already have a row where UNIT is "CTN". If you need to filter that for specific ITEMNO values you simply adjust the WHERE clause. If that works correctly, you can use that with your insert statement to then insert the desired rows.
insert into dbo.ICUNIT (...)
select distinct icu.ITEMNO, 'CTN', '20220509', '22513927', 'ADMIN', 'AU', '1'
from ...
;

SQL unique PK for grouped data in SP

I am trying to build a temp table with grouped data from multiple tables (in an SP), I am successful in building the data set however I have a requirement that each grouped row have a unique id. I know there are ways to generate unique ids for each row, However the problem I have is that I need the id for a given row to be the same on each run regardless of the number of rows returned.
Example:
1st run:
ID Column A Column B
1 apple 15
2 orange 10
3 grape 11
2nd run:
ID Column A Column B
3 grape 11
The reason I want this is because i am sending this data up to SOLR and when I do a delta I need to have the ID back for the same row as its trying to re-index
Any way I can do this?
Not sure if this will help, not entirely confident of your wider picture, but ...
As your new data is assembled, log each [column a] value in a table of your own.
Give that table an IDENTITY column to do the numbering for you.
Now you can join any new data sets to your lookup table and you'll have a persistent number for each column A.
You just need to ensure that each time you query new data, you add new values to the lookup table.
create table dbo.myRef(
idx int identity(1,1)
,[A] nvarchar(100)
)
General draft as below ...
--- just simulating some input data here
with cte as (
select 'apple' as [A], 15 as [B]
UNION
select 'orange' as [A], 10 as [B]
UNION
select 'banana' as [A], 4 as [B]
)
select * into #temp from cte;
-- Put any new values into the lookup table
-- and they will be assigned a new index number by the identity column
insert into dbo.myRef([A])
select distinct [A]
from #temp where [A] not in (select [A] from dbo.myRef)
-- now pull your original data for output, joining to the lookup table to get a ref number.
select T.*,R.idx
from #temp T
inner join
oer.myRef R
on T.[A] = R.[A]
Sorry for the late reply, i was stuck with something else, however i solved my own issue.
I built 2 temp tables one with all the data from the various tables (#master) and another temp table (#final) to house all the grouped data with an empty column for ID
Next i did a concat(column1, '-',column2,'-', column3) on 3 columns from the #master and updated the #final table based on the type
this helped me to get the same concat ids on each run

SQL Server FullText Search with Weighted Columns from Previous One Column

In the database on which I am attempting to create a FullText Search I need to construct a table with its column names coming from one column in a previous table. In my current implementation attempt the FullText indexing is completed on the first table Data and the search for the phrase is done there, then the second table with the search results is made.
The schema for the database is
**Players**
Id
PlayerName
Blacklisted
...
**Details**
Id
Name -> FirstName, LastName, Team, Substitute, ...
...
**Data**
Id
DetailId
PlayerId
Content
DetailId in the table Data relates to Id in Details, and PlayerId relates to Id in Players. If there are 1k rows in Players and 20 rows in Details, then there are 20k rows in Data.
WITH RankedPlayers AS
(
SELECT PlayerID, SUM(KT.[RANK]) AS Rnk
FROM Data c
INNER JOIN FREETEXTTABLE(dbo.Data, Content, '"Some phrase like team name and player name"')
AS KT ON c. DataID = KT.[KEY]
GROUP BY c.PlayerID
)
…
Then a table is made by selecting the rows in one column. Similar to a pivot.
…
SELECT rc.Rnk,
c.PlayerID,
PlayerName,
TeamID,
…
(SELECT Content FROM dbo.Data data WHERE DetailID = 1 AND data.PlayerID = c.PlayerID) AS [TeamName],
…
FROM dbo.Players c
JOIN RankedPlayers rc ON c. PlayerID = rc. PlayerID
ORDER BY rc.Rnk DESC
I can return a ranked table with this implementation, the aim however is to be able to produce results from weighted columns, so say the column Playername contributes to the rank more than say TeamName.
I have tried making a schema bound view with a pivot, but then I cannot index it because of the pivot. I have tried making a view of that view, but it seems the metadata is inherited, plus that feels like a clunky method.
I then tried to do it as a straight query using sub queries in the select statement, but cannot due to indexing not liking sub queries.
I then tried to join multiple times, again the index on the view doesn't like self-referencing joins.
How to do this?
I have come across this article http://developmentnow.com/2006/08/07/weighted-columns-in-sql-server-2005-full-text-search/ , and other articles here on weighted columns, however nothing as far as I can find addresses weighting columns when the columns were initially row data.
A simple solution that works really well. Put weight on the rows containing the required IDs in another table, left join that table to the table to which the full text search had been applied, and multiply the rank by the weight. Continue as previously implemented.
In code that comes out as
DECLARE #Weight TABLE
(
DetailID INT,
[Weight] FLOAT
);
INSERT INTO #Weight VALUES
(1, 0.80),
(2, 0.80),
(3, 0.50);
WITH RankedPlayers AS
(
SELECT PlayerID, SUM(KT.[RANK] * ISNULL(cw.[Weight], 0.10)) AS Rnk
FROM Data c
INNER JOIN FREETEXTTABLE(dbo.Data, Content, 'Karl Kognition C404') AS KT ON c.DataID = KT.[KEY]
LEFT JOIN #Weight cw ON c.DetailID = cw.DetailID
GROUP BY c.PlayerID
)
SELECT rc.Rnk,
...
I'm using a temporary table here for evidence of concept. I am considering adding a column Weights to the table Details to avoid an unnecessary table and left join.

How can i search any string value from a manipulated coloumn of table in oracle sql

How can I search any string value from a manipulated column of table like:
SELECT SUBSTR(DESCR,1,8) AS MYDES FROM STATION WHERE descr='ABERDEEN';
I want to search 'ABERDEEN' from SUBSTR(DESCR,1,8) or 'MYDES' column but in my case 'ABERDEEN' is still searched from DESCR column. How can I search it from the new manipulated 'MYDES' column (oracle, sql)?
If you want to filter the rows which has the substr as ABERDEEN in the column descr, then use the function in the filter predicate.
For example,
SELECT * FROM STATION WHERE SUBSTR(DESCR,1,8)='ABERDEEN';
To include the new column in the output along with other columns,
SELECT t.*,
SUBSTR(DESCR,1,8) AS MYDES
FROM STATION
WHERE SUBSTR(DESCR,1,8)='ABERDEEN';
You can use LIKE in where as below :
SELECT SUBSTR(DESCR,1,8) AS MYDES FROM STATION WHERE descr like 'ABERDEEN%';

Resources