I am newbie to hive, I am having issue with complex data map retrieval, when I try to retrieve particular key value pair, it is also pulling null from the record.
Describe of my table phone
name string
ph map<string,int>
This is my query
select ph["yy"] from phone;
and this is my data
gua {"p":123456}
xxx {"yy":7987897}
The result after executing the query is
hive> select ph["yy"] from phone;
OK
NULL
7987897
I am wondering why it is throwing null value .
Please help I would greatly appreciate it .
This is in-build. This is valid for Array type columns as well. To avoid NULLs use the WHERE clause.
-- Programming with Hive :
ARRAY indexing is 0-based, as in Java. Here is a query that selects the first element of the subordinates array:
hive> SELECT name, subordinates[0] FROM employees;
John Doe Mary Smith
Mary Smith Bill King
Todd Jones NULL
Bill King NULL
Note that referencing a nonexistent element returns NULL. Also, the extracted STRING values are no longer quoted!
Related
I have a Orable Table with one CLOB column which contains JSON data. I need a query which will search within the CLOB data.
I have used the condition where DBMS_LOB.instr(colName,'apple:')>0 which gives the records having apple:. However, I need to the query to return records with any number of apples other than blank, meaning, the json apple key should have a value.
I am thinking of something like where DBMS_LOB.instr(colName,'apple:**X**')>0, where X can be any number not null. I tried regexp_instr but it seems this is not correct for CLOB.
Are there any alternatives to solve this?
Generic string functions for parsing JSON inputs are dangerous - you will get false positives, for example, when something that looks like a JSON object is in fact embedded in a string value. (Illustrated by ID = 101 in my example below.)
The ideal scenario is that you are using Oracle 19 or higher; in that case you can use a simple call to json_exists as illustrated below. In the sample table I create, the first JSON string does not contain a member named apple. In the second row, the string does contain a member apple but the value is null. The first query I show (looking for all JSON with an apple member) will include this row in the output. The last query is what you need: it adds a filter so that a JSON string must include at least one apple member with non-null value (regardless of whether it also includes other members named apple, possibly with null value).
create table sample_data
( id number primary key
, colname clob check (colname is json)
);
insert into sample_data
values (101, '{name:"Chen", age:83, values:["{apple:6}", "street"]}');
insert into sample_data
values (102, '{data: {fruits: [{orange:33}, {apple:null}, {plum:44}]}}');
insert into sample_data
values (103, '[{po:3, "prods":[{"apple":4}, {"banana":null}]},
{po:4, "prods":null}]');
Note that I intentionally mixed together quoted and unquoted member names, to verify that the queries below work correctly in all cases. (Remember also that member names in JSON are case sensitive, even in Oracle!)
select id
from sample_data
where json_exists(colname, '$..apple')
;
ID
---
102
103
This is the query you need. Notice the .. in the path (meaning - find an object member named apple anywhere in the JSON) and the filter at the end.
select id
from sample_data
where json_exists(colname, '$..apple?(# != null)')
;
ID
---
103
You can use regexp_like function for this:
where regexp_like(colName,'apple : [0-9]')
I have a column called people in my table which is a statement. I need to extract only the names from that column.
people:
Ramu is a good dancer.
Raj is the highest scorer in maths.
I need to extract only names (ramu,raj) from these statements.
Hint: names before is since all statements has a word is here.
I don't how to extract in postgresql
Use split_part():
with people(statement) as (
values
('Ramu is a good dancer.'),
('Raj is the highest scorer in maths.')
)
select split_part(statement, ' ', 1) as name
from people;
name
------
Ramu
Raj
(2 rows)
I am VERY new to SQL and I am having a little trouble.
Let's say I have a table, called data, with two columns, class, and name.
I want to create the column math if it doesn't exist, and give it a value of John.
I can do this with:
INSERT INTO data VALUES ('math','John')
But if I change John to Steve, I want math to have a value of "John","Steve".
But instead, it creates another row called "math" with a value of "Steve", how can I make this insert into the same column?
Thanks
I would strongly recommend against storing a CSV list of names in your table. CSV is hard to query, update, and maintain. Actually, there is nothing at all wrong with your current approach:
class | name
math | John
math | Steve
Data in this format can easily be queried, because it is relational. And if you need to add, update, or remove a name associated with a class, it becomes a one record affair without having to deal with CSV. Note that if you really need a CSV representation, you can still achieve that using SQLite's GROUP_CONCAT() function:
SELECT class, GROUP_CONCAT(name, ',') AS names
FROM yourTable
GROUP BY class
Not totally sure about SQLite but the normal command usually is something like:
ALTER TABLE table_name
ADD column_name datatype
Then insert into
I have the following "table1" :
NAME JOB
Mary pilot, astronaut, cook
John astronaut, biker
Michael rider
Rita teacher, doctor
I want to select all people who are an astronaut OR a doctor. It should return Mary, John and Rita.
I currently have:
select name from table1
where 'astronaut,doctor' in (select regexp_substr(table1.job,'[^'',]+', 1, level)
from dual
connect by regexp_substr(table1.job, '[^'',]+', 1, level) is not null)
However, I don't want to compare the whole string on the left-hand side, instead I want to iterate through it.
Note: I'm getting the left-hand argument as an input argument, so it must be parsed inside the sql.
You should fix your data format. You are trying to store lists in a column, and that is a bad idea. You should be using a junction table rather than delimited values.
Sometimes, we are stuck with other people's bad design decisions. Oracle does have powerful regular expression operators. This does allow:
select name, job
from table1
where regexp_like(job, replace('astronaut,doctor', ',', '|');
I have a table, users, in an Oracle 9.2.0.6 database. Two of the fields are varchar - last_name and first_name.
When rows are inserted into this table, the first name and last name fields are supposed to be in all upper case, but somehow some values in these two fields are mixed case.
I want to run a query that will show me all of the rows in the table that have first or last names with lowercase characters in it.
I searched the net and found REGEXP_LIKE, but that must be for newer versions of oracle - it doesn't seem to work for me.
Another thing I tried was to translate "abcde...z" to "$$$$$...$" and then search for a '$' in my field, but there has to be a better way?
Thanks in advance!
How about this:
select id, first, last from mytable
where first != upper(first) or last != upper(last);
I think BQ's SQL and Justin's second SQL will work, because in this scenario:
first_name last_name
---------- ---------
bob johnson
Bob Johnson
BOB JOHNSON
I want my query to return the first 2 rows.
I just want to make sure that this will be an efficient query though - my table has 500 million rows in it.
When you say upper(first_name) != first_name, is "first_name" always pertaining to the current row that oracle is looking at? I was afraid to use this method at first because I was afraid I would end up joining this table to itself, but they way you both wrote the SQL it appears that the equality check is only operating on a row-by-row basis, which would work for me.
If you are looking for Oracle 10g or higher you can use the below example. Consider that you need to find out the rows where the any of the letter in a column is lowercase.
Column1
.......
MISS
miss
MiSS
In the above example, if you need to find the values miss and MiSS, then you could use the below query
SELECT * FROM YOU_TABLE WHERE REGEXP_LIKE(COLUMN1,'[a-z]');
Try this:
SELECT * FROM YOU_TABLE WHERE REGEXP_LIKE(COLUMN1,'[a-z]','c'); => Miss, miss lower text
SELECT * FROM YOU_TABLE WHERE REGEXP_LIKE(COLUMN1,'[A-Z]','c'); => Miss, MISS upper text
SELECT *
FROM mytable
WHERE FIRST_NAME IN (SELECT FIRST_NAME
FROM MY_TABLE
MINUS
SELECT UPPER(FIRST_NAME)
FROM MY_TABLE )
for SQL server where the DB collation setting is Case insensitive use the following:
SELECT * FROM tbl_user WHERE LEFT(username,1) COLLATE Latin1_General_CS_AI <> UPPER(LEFT(username,1))