I imported a dataset that has a object in the column GENRES and I'm wondering if there is a (beginner's) way to query the data inside each entry.
[{"id": 12, "name": "Adventure"}, {"id": 10751, "name": "Family"}, {"id": 14, "name": "Fantasy"}]
For example, if I would want to query all the movies having the "id": 12.
The dataset comes from here
If you store the data with an IS JSON constraint, then you can use JSON_TABLE to expand the JSON into columns.
--Create a table.
create table tmdb(movie_id number, genres clob check (genres is json));
--Insert a test row.
insert into tmdb
values(1, '[{"id": 12, "name": "Adventure"}, {"id": 10751, "name": "Family"}, {"id": 14, "name": "Fantasy"}]');
--Use JSON_TABLE to convert JSON to relational data.
select movie_id, id, name
from tmdb,
json_table
(
genres, '$[*]'
columns
(
id number path '$.id',
name varchar2(4000) path '$.name'
)
) as jt;
--Results:
MOVIE_ID ID NAME
-------- ----- ---------
1 12 Adventure
1 10751 Family
1 14 Fantasy
Related
I'm using the Confluent Oracle CDC Connector https://docs.confluent.io/cloud/current/connectors/cc-oracle-cdc-source/cc-oracle-cdc-source.html. When I insert a record with a date column, the corresponding JSON that the connector outputs is an integer.
SQL TABLE (NOTE the PRODUCT_OFFERDATE's type)
describe DB_USER.DF_PRODUCT;
Name Null? Type
----------------------------------------
PRODUCT_ID NOT NULL VARCHAR2(50)
PRODUCT_NAME NOT NULL VARCHAR2(75)
PRODUCT_DESCRIPTION NOT NULL VARCHAR2(150)
PRODUCT_PRICE NOT NULL NUMBER(10,2)
PRODUCT_OFFERDATE NOT NULL DATE
PRODUCT_BUNDLED VARCHAR2(1)
LAST_TIMESTAMP NOT NULL TIMESTAMP(6)
Inserting a new record --
INSERT INTO DB_USER.DF_PRODUCT VALUES (15, 'Sample product', 'Sample description', 11.50, DATE '2008-11-11', 'N', current_timestamp);
Kafka record --
{
"PRODUCT_ID": "15",
"PRODUCT_NAME": "Sample product",
"PRODUCT_DESCRIPTION": "Sample description",
"PRODUCT_PRICE": 11.5,
"PRODUCT_OFFERDATE": 14194,
"PRODUCT_BUNDLED": "N",
"LAST_TIMESTAMP": 1676286930721,
"table": "ORCL.DB_USER.DF_PRODUCT_2",
"scn": "1427886",
"op_type": "I",
"op_ts": "1676247330000",
"current_ts": "1676247331513",
"row_id": "AAAF6yAAAAAAAM7AAI",
"username": "ADMIN"
}
I've tried using the oracle.date.mapping and set to date but it still outputs the same format. The workaround I have at the moment is to create an SMT. It won't be ideal since I'll have more columns that will have a DATE type.
Any help would be appreciated.
INSERT INTO ABOARD(BNO, BNAME, BPW, BTITLE, BCONTENT, BDATE, BGROUP,
BSTEP, BINDENT, COMCNT, ISDEL, HAVEFILE)
VALUES(#{bno}, #{bname }, #{bpw },
#{btitle }, #{bcontent }, SYSDATE, GROUPSEQ.NEXTVAL, 0, 0, 0,'N','N')
This is my board table.
I want to change the last column "HAVEFILE" if I add file to insert the board when I register.
below table is the attachment file. How to join two table or make a query?
CREATE TABLE MP_FILE
(
FILE_NO NUMBER,
BNO NUMBER NOT NULL,
ORG_FILE_NAME VARCHAR2(260) NOT NULL,
STORED_FILE_NAME VARCHAR2(36) NOT NULL,
FILE_SIZE NUMBER,
REGDATE DATE DEFAULT SYSDATE NOT NULL,
DEL_GB VARCHAR2(1) DEFAULT 'N' NOT NULL,
PRIMARY KEY(FILE_NO)
);
I use Vertica 9.2.1 in EON-mode.I have a fact table with a column that holds JSON strings. I want to load this data together with some identifiers from the fact table into a flextable. So that we can run analysis on that data. What I want to avoid is, loading all the necessary data onto an ETL machine to transform the data and then load it into the flextable, since all the data is already available in Vertica. How can I tell Vertica to parse a VARCHAR column as JSON?
CREATE TABLE public.tmp_facts ("id" INTEGER, "user_id" VARCHAR(64), "event_type" VARCHAR(50), /* other columns omitted */ "additional" VARCHAR(65000));
INSERT INTO public.tmp_facts ("id", "user_id", "event_type", "additional")
SELECT 1, 'user1', 'event1', '{"os":"Android", "time":"'||NOW()||'"}';
CREATE FLEX TABLE public.fact_additional
(
"id" INTEGER NOT NULL,
"user_id" VARCHAR(64) NOT NULL,
"event_type" VARCHAR(50)
);
INSERT INTO public.fact_additional ("id", "user_id", "event_type")
SELECT "id", "user_id", "event_type", "additional" FROM tmp_facts;
SELECT "additional", "additional.os", "additional[os]" FROM fact_additional;
I expected that the last query outputs for at least one column Android
You need to pass the additional column through MapJSONExtractor() function when inserting from public.tmp_facts into public.fact_additional
INSERT INTO public.fact_additional ("id", "user_id", "event_type")
SELECT "id",
"user_id",
"event_type",
MapJSONExtractor("additional") as additional
FROM tmp_facts;
SELECT "additional"['os'] as os FROM fact_additional;
os
---------
Android
(1 row)
Notice the usage of single / double quotes at the appropriate places.
I want to parse and insert below JSON to relational table using PL/SQL & ORDS. but I'm stuck at sizes part of below JSON
{
"order_number": "302523001",
"sizes": {
"34": 2,
"33": 4,
"32": 7,
"36": 8
}
}
I am using below code to process above
INSERT INTO test_sizes_tbl
SELECT * FROM json_table
(l_po format json, '$' COLUMNS (
order_number varchar2 path '$.order_number',
NESTED path '$.sizes[*]'
COLUMNS (
size_name varchar2 path '$.key',
size_value varchar2 path '$.value')));
Sizes e.g. 32, 33, 34, 36 are dynamic values and there is no way to fix them as key. I need to pick these sizes dynamically and insert into table. How to parse above JSON?
I'm not if am I using sqlfidle incorrectly or if this is missing functionality?
Steps to reproduce:
Select oracle option (top left)
create table and insert data:
CREATE TABLE products
("P_Id" int, "ProductName" varchar2(10), "UnitPrice" numeric, "UnitsInStock" int, "UnitsOnOrder" int)
//
INSERT ALL
INTO products ("P_Id", "ProductName", "UnitPrice", "UnitsInStock", "UnitsOnOrder")
VALUES (1, 'Jarlsberg', 10.45, 16, 15)
INTO products ("P_Id", "ProductName", "UnitPrice", "UnitsInStock", "UnitsOnOrder")
VALUES (2, 'Mascarpone', 32.56, 23, NULL)
INTO products ("P_Id", "ProductName", "UnitPrice", "UnitsInStock", "UnitsOnOrder")
VALUES (3, 'Gorgonzola', 15.67, 9, 20)
SELECT * FROM dual
//
Build schema
run query and verify result is correct
select * from products
Run query with column name (any) and get the error:
select ProductName from products
error given:
ORA-00904: "PRODUCTNAME": invalid identifier
Is my query wrong or isn't it possible on sqlfiddle to use the column names in the select query? Do I have any workarounds to keep testing my query?
[TL;DR] The simplest thing to do is to never use double quotes around object names and just let oracle manage the case-sensitivity in its default manner.
However, you can use double-quotes in SQLFiddle:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE products
("P_Id" int, "ProductName" varchar2(10), "UnitPrice" numeric, "UnitsInStock" int, "UnitsOnOrder" int)
//
INSERT ALL
INTO products ("P_Id", "ProductName", "UnitPrice", "UnitsInStock", "UnitsOnOrder")
VALUES (1, 'Jarlsberg', 10.45, 16, 15)
INTO products ("P_Id", "ProductName", "UnitPrice", "UnitsInStock", "UnitsOnOrder")
VALUES (2, 'Mascarpone', 32.56, 23, NULL)
INTO products ("P_Id", "ProductName", "UnitPrice", "UnitsInStock", "UnitsOnOrder")
VALUES (3, 'Gorgonzola', 15.67, 9, 20)
SELECT * FROM dual
//
Query 1:
SELECT "ProductName" FROM products
Results:
| ProductName |
|-------------|
| Jarlsberg |
| Mascarpone |
| Gorgonzola |
Run query with column name (any) and get the error:
select ProductName from products
error given:
ORA-00904: "PRODUCTNAME": invalid identifier
Oracle databases are, by default, case sensitive; however, they will also, by default, convert everything to upper-case so that the case sensitivity is abstracted from you, the user. It is only when you use double-quotes that Oracle will use the case you specify for the identifier.
Since you used quoted identifiers in the CREATE TABLE statement you will also need to use quoted identifiers in the SELECT statements with the exact case used in table creation.
So, the column name is not ProductName it is "ProductName" (with the double-quotes).
A better solution is to not use double quotes:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE products(
P_Id int,
ProductName varchar2(10),
UnitPrice numeric,
UnitsInStock int,
UnitsOnOrder int
)
//
INSERT INTO products ( P_Id, ProductName, UnitPrice, UnitsInStock, UnitsOnOrder )
SELECT 1, 'Jarlsberg', 10.45, 16, 15 FROM DUAL UNION ALL
SELECT 2, 'Mascarpone', 32.56, 23, NULL FROM DUAL UNION ALL
SELECT 3, 'Gorgonzola', 15.67, 9, 20 FROM DUAL
//
Query 1:
SELECT ProductName FROM products
Results:
| PRODUCTNAME |
|-------------|
| Jarlsberg |
| Mascarpone |
| Gorgonzola |
In Oracle when you use mixed case names, you must always use double quotes around them. It assumes that identifiers will be all upper case.
So to access a column called ProductName you should run:
select "ProductName" from products
I see your column names between double quotes " ".
This can use when you want to entitle your column names with special charecters.
So you can use :
select "ProductName" from products;