Hive explode results in table - hive

Could someone tell me what's wrong with this code? If I run the select statement only, then its returning the results.
The code is working if I remove one of the line "location" or "stored as textfile".
Also please let me know if I can specify 'delimiter' too.
create table exploderesults
location '/user/cloudera/sometest'
stored as textfile
as
select id,ph as phone, ct as city from explodetest
lateral view explode(phone)p as ph
lateral view explode(city)c as ct;
Thanks

Swap the two rows stored as and location. They have to be in a particular order according to the manual
create table exploderesults
stored as textfile
location '/user/cloudera/sometest'
as
select id,ph as phone, ct as city from explodetest
lateral view explode(phone)p as ph
lateral view explode(city)c as ct;
If you want to specify a delimiter,
create table exploderesults
row format delimited fields terminated by ','
stored as textfile
location '/user/cloudera/sometest'
as
select id,ph as phone, ct as city from explodetest
lateral view explode(phone)p as ph
lateral view explode(city)c as ct;

Related

I need to create a VIEW from an existing TABLE and MAP an additional COLUMN to that VIEW

I am fairly new to SQL. What I am trying to do is create a view from an existing table. I also need to add a new column to the view which maps to the values of an existing column in the table.
So within the view, if the value in a field for Col_1 = A, then the value in the corresponding row for New_Col = C etc
Does this even make sense? Would I use the CASE clause? Is mapping in this way even possible?
Thanks
The best way to do this is to create a mapping or lookup table
For example consider the following LOOKUP table.
COL_A NEW_VALUE
---- -----
A C
B D
Then you can have a query like this:
SELECT A.*, LOOK.NEW_VALUE
FROM TABLEA AS A
JOIN LOOKUP AS LOOK ON A.COL_A = LOOK.COL_A
This is what DimaSUN is doing in his query too -- but in his case he is creating the table dynamically in the body of the query.
Also note, I'm using a JOIN (which is an inner join) so only results in the lookup table will be returned. This could filter the results. A LEFT JOIN there would return all data from A but some of the new columns might be null.
Generally, a view is an instance of a table/a replica provided that there is no alteration to the original table. So, as per your query you can manipulate the data and columns in a view by using case.
Create View viewname as
Select *,
case when column=a.value then 'C'
....
ELSE
END
FROM ( Select * from table) a
If You have restricted list of replaced values You may hardcode that list in query
select T.*,map.New_Col
from ExistingTable T
left join (
values
('A','C')
,('B','D')
) map (Col_1,New_Col) on map.Col_1 = T.Col_1
In this sample You hardcode 'A' -> 'C' and 'B' -> 'D'
In general case You better may to use additional table ( see Hogan answer )

How to get view modification date using SQL query?

I'm trying to log the state of views in my Oracle DB. For each view I want to get it's text and the last modification date.
I successfully got view text by using the following query:
select text from ALL_VIEWS where upper(view_name) like upper(<view_name>);
In SQL Navigator I also can see the modification date for each view. Is it possible to get this date by SQL query?
User need to join to user_objects. Something like:
select v.view_name, o.last_ddl_time, v.text
from user_objects o
join user_views v
on v.view_name = o.object_name
where v.view_name = upper( '&vname' )

Create view in sql server "names in each view or function must be unique"

I'm trying to create view in sql server 2012, but I have this error message
Column names in each view or function must be unique. Column name 'Lastname' in view or function 'vFileImportDPERManagers' is specified more than once.
this is my view's code :
GO
CREATE VIEW [dbo].[vFileImportDPERManagers]
AS
SELECT M.*,
Managers.*
FROM dbo.vFileImportDPERDebtors M WITH (NOLOCK)
CROSS APPLY
(
SELECT
M1.Man.value('#j11','varchar(20)') as ManagerKey,
M1.Man.value('#j12','varchar(50)') as Lastname,
M1.Man.value('#j13','varchar(50)') as Firstname,
M1.Man.value('#j14','numeric') as ManagerFunctionId
FROM DebtorXml.nodes('d1/d36/t324/j1') as M1(Man)
) as Managers
GO
In your case the table dbo.vFileImportDPERDebtors will have a column called 'Lastname'. If you select all of your columns by name (i.e. expand * into names) you can alias one or both of the Lastname columns, SELECT M.Lastname as Lastname1, Managers.Lastname as Lastname2.... It's generally considered best-practice not to use 'SELECT *'.

Check if a list of items already exists in a SQL database

I want to create a group of users only if the same group does not exist already in the database.
I have a GroupUser table with three columns: a primary key, a GroupId, and a UserId. A group of users is described as several lines in this table sharing a same GroupId.
Given a list of UserId, I would like to find a matching GroupId, if it exists.
What is the most efficient way to do that in SQL?
Let say your UserId list is stored in a table called 'MyUserIDList', the following query will efficiently return the list of GroupId containing exactly your user list. (SQL Server Syntax)
Select GroupId
From (
Select GroupId
, count(*) as GroupMemberCount
, Sum(case when MyUserIDList.UserID is null then 0 else 1 End) as GroupMemberCountInMyList
from GroupUser
left outer join MyUserIDList on GroupUser.UserID=MyUserIDList.UserID
group by GroupId
) As MySubQuery
Where GroupMemberCount=GroupMemberCountInMyList
There are couple of ways of doing this. This answer is for sql server only (as you have not mentioned it in your tags)
Pass the list of userids in comma seperated to a stored procedure and in the SP create a dynamic query with this and use the EXEC command to execute the query. This link will guide you in this regard
Use a table-valued parameter in a SP. This is applicable to sql server 2008 and higher only.
The following link will help you get started.
http://www.codeproject.com/Articles/113458/TSQL-Passing-array-list-set-to-stored-procedure-MS
Hope this helps.
One other solution is that you convert the input list into a table. This can be done with various approaches. Unions, temporary tables and others. A neat solution combines the answer of
user1461607 for another question here on SO, using a comma-separated string.
WITH split(word, csv) AS (
-- 'initial query' (see SQLite docs linked above)
SELECT
'', -- place holder for each word we are looking for
'Auto,A,1234444,' -- items you are looking for
-- make sure the list ends with a comma !!
UNION ALL SELECT
substr(csv, 0, instr(csv, ',')), -- each word contains text up to next ','
substr(csv, instr(csv, ',') + 1) -- next recursion parses csv after this ','
FROM split -- recurse
WHERE csv != '' -- break recursion once no more csv words exist
) SELECT word, exisiting_data
FROM split s
-- now join the key you want to check for existence!
-- for demonstration purpose, I use an outer join
LEFT OUTER JOIN (select 'A' as exisiting_data) as t on t.exisiting_data = s.word
WHERE s.word != '' -- make sure we clamp the empty strings from the split function
;
Results in:
Auto,null
A,A
1234444,null

ORA-01731: circular view definition encountered

we are migrating over to oracle from sql server side.
on sqlserver we used to have a view like the following
create view blah
AS
Select column1,
column2
FROM blah;
but doing this on oracle produces circular view error.
is this not allowed on oracle side?
You cannot have a view reference itself. It logically does not make sense. A view is essentially a cached query whose results are displayed as a table. How can a query refer to itself?
Indeed, circular view definitions are not allowed in Oracle. If you have a circular view definition, then you likely have a bug in your database code that should be addressed. Perhaps the translation from SQL server to Oracle was flawed and accidentally introduced this circular definition?
You can actually do this in ORACLE, but it is more fragile, as you need to explicitly list the output columns of your CTE. So if you change the tables, you need to manually update the CTE.
Here is an example from our db, showing how to calculate the hierarchical depth of the a record...
CREATE OR REPLACE VIEW deploy.PHARMACYDISPENSE_EX
AS
WITH SRC (
PDID, WAREID, GCN_SEQNO, QTY, UOFM, XACTDTTM, CREATEDON, PROCESSEDON,
XACTTYPE, OPDID, CLOSEDON, BYPASSEDON, BYPASSEDBY, ITEMNO, LOTNO,
EXP_DATE, VOLUMETYPE, POTYPE, DEPTH
) AS (
SELECT D.PDID, D.WAREID, D.GCN_SEQNO, D.QTY, D.UOFM, D.XACTDTTM,
D.CREATEDON, D.PROCESSEDON, D.XACTTYPE, D.OPDID, D.CLOSEDON,
D.BYPASSEDON, D.BYPASSEDBY, D.ITEMNO, D.LOTNO, D.EXP_DATE,
D.VOLUMETYPE, D.POTYPE, 0 FROM deploy.PHARMACYDISPENSE D
WHERE OPDID IS NULL
UNION ALL
SELECT D.PDID, D.WAREID, D.GCN_SEQNO, D.QTY, D.UOFM, D.XACTDTTM,
D.CREATEDON, D.PROCESSEDON, D.XACTTYPE, D.OPDID, D.CLOSEDON,
D.BYPASSEDON, D.BYPASSEDBY, D.ITEMNO, D.LOTNO, D.EXP_DATE,
D.VOLUMETYPE, D.POTYPE, (S.DEPTH + 1)
FROM deploy.PHARMACYDISPENSE D JOIN SRC S ON S.PDID = D.OPDID
)
SELECT PD.*
FROM SRC PD;
The important part here is the WITH SRC (<output column list>) AS .... You need that output column list. So it is possible, and does work, it just takes a bit more code than in SQL Server.
Your example is incomplete - well at least doesn't show the pertinent parts.:
-- create a table
CREATE TABLE Scrap
(fieldName VARCHAR2(20));
-- create a view
CREATE VIEW ScrapVW1
AS
SELECT * FROM Scrap;
-- create a second view that uses the first view
CREATE VIEW ScrapVW2
AS
SELECT * FROM Scrap
UNION ALL
SELECT * FROM ScrapVW1;
-- recreate the first view that references the 2nd view which contains a reference to itself
CREATE OR REPLACE VIEW SCRAP_VW1
AS
SELECT * FROM ScrapVW2;
Gives a circular reference error when you try to recreate ScrapVW1. I would guess you have some unintentional name collision going on in your conversion. If it's quite complex I'd get rid of the 'CREATE OR REPLACE VIEW' syntax and just use CREATE VIEW which would then give you 'ORA-00955 Name already used' error.
Oracle deals with Hierarchical problems different than SQL apparently. Instead of self referring view, you can use connect by clause
SELECT employee_id, last_name, manager_id
FROM employees
CONNECT BY PRIOR employee_id = manager_id;