Hadoop - Hive sub-queries - Not In Clause - hadoop

I'm trying to run the following query on Hive:
SELECT COUNT(*)
FROM mydata
WHERE store NOT IN (SELECT store_out
FROM ( SELECT a.store as store_out, COUNT(*) AS CNT
FROM mydata a
GROUP BY store) TB1
WHERE CNT > AVG(CNT) + STDDEV(CNT) AND CNT < AVG(CNT) - STDDEV(CNT))
But I'm getting the following errors:
Error while compiling statement: FAILED: SemanticException [Error 10249]: Line 3:6 Unsupported SubQuery Expression 'store': Correlating expression cannot contain unqualified column references.
How can I write this query in another way?
Thanks!

I don't have you exact data so it is hard to verify this but I would do something like
SELECT COUNT(*)
FROM (
SELECT a.*
, flg
FROM mydata a
LEFT OUTER JOIN (
SELECT store_out, flg
FROM (
SELECT store_out
, cnt
, 1 AS flg
, AVG(cnt) OVER () AS avg_cnt
, STDDEV_SAMP(cnt) OVER () AS std_cnt
FROM (
SELECT store AS store_out
, COUNT(*) AS cnt
FROM mydata
GROUP BY store ) x
) y
WHERE cnt > avt_cnt + std_cnt AND cnt < avg_cnt - std_cnt ) z
ON a.store = z.store_out ) final
WHERE flg IS NULL
Basically, left join the subquery and create a dummy column. That column won't exists in the main table so where all the flg values are NULL, these are the stores you want. Hope this helps.

Related

CTE inside Table-valued function in Oracle

I'm trying to write a Table-valued function in oracle, which contains a CTE.
I've been able to do it in SQL Server in this way:
ALTER FUNCTION [dbo].[region_parents]
(
#regionId INT
)
RETURNS TABLE
AS
RETURN
(
WITH cte AS
(
SELECT id, owner_region_id FROM regions WHERE id = #regionId
UNION ALL
SELECT r.id, r.owner_region_id
FROM cte INNER JOIN
regions r ON cte.owner_region_id = r.id
)
SELECT id
FROM cte
)
This is needed in order to call it in a cross apply:
SELECT *
FROM shops s
...
...
...
INNER JOIN locations l ON s.location_id = l.id
LEFT JOIN location_criteria lc ON lc.location_id = l.id
CROSS APPLY region_parents(l.region_id) r
In Oracle, I've tried to do it in this way, using User-Defined Datatypes:
CREATE OR REPLACE TYPE TABLE_RES_OBJ AS OBJECT (
id NUMBER
);
CREATE OR REPLACE TYPE TABLE_RES AS TABLE OF TABLE_RES_OBJ;
CREATE OR REPLACE FUNCTION region_parents (regionId IN INTEGER)
RETURN TABLE_RES
IS
cteresult TABLE_RES;
BEGIN
WITH cte(id, owner_region_id) AS
(
SELECT id AS id, owner_region_id AS owner_region_id FROM regions WHERE id = regionId
UNION ALL
SELECT r.id, r.owner_region_id
FROM cte INNER JOIN
regions r ON cte.owner_region_id = r.id
)
SELECT TABLE_RES(id)
BULK COLLECT INTO cteresult
FROM cte;
RETURN cteresult;
END;
/
The problem is that I obtain the following error:
PL/SQL: ORA-00932: inconsistent datatypes: expected UDT got NUMBER
I've also tried to achieve it in this way, without success.
Seems to be a simple distraction: "SELECT TABLE_RES(id)" should be "SELECT TABLE_RES_OBJ(id)".
It isn't anything to do with the CTE. You're trying to select a table object, not a simple object that is an element/row in that table. This:
SELECT TABLE_RES(id)
BULK COLLECT INTO cteresult
FROM cte;
should be:
SELECT TABLE_RES_OBJ(id)
BULK COLLECT INTO cteresult
FROM cte;
fiddle

Pivot query issue while using the comparison operation

When i try run the below query i'm getting this error
ORA-00917: missing comma
00917. 00000 - "missing comma"
*Cause:
*Action: Error at Line: 26 Column: 22
Query:
select * from
(select 'india',po.team,pa.NAME,pa.userid,me.amount as RN
from
port po,
switch pa,
merchant me
where po.SEQNO=pa.SEQNO
and (pa.SEQNO=me.SEQNO and RN is not null))
PIVOT (
count(*) for RN in(RN<1,RN-20.01)
)
I want display the percentage columns as <=1, between 10 to 20 and >20 by using the pivot logic
Use a case statement in your initial sub-query:
select *
from (
select *
from (
select 'india',
po.team,
pa.NAME,
pa.userid,
CASE
WHEN me.amount <= 1 THEN '<1'
WHEN me.amount BETWEEN 10 AND 20 THEN '10-20'
WHEN me.amount > 20 THEN '>20'
END as RN
from port po
INNER JOIN switch pa
ON ( po.SEQNO=pa.SEQNO )
INNER JOIN merchant me
ON ( pa.SEQNO=me.SEQNO )
)
where RN is not null
) PIVOT (
count(*) for RN in( '<1', '10-20', '>20' )
);

Common table expression Alias Name issue

I am trying to insert column values of BREAK_TIME and DIFF_OUT into my base table ezlabor_final_ak using Common Table Expression(CTE) but it is giving error message
ORA-00904: "B"."IN_TIME": invalid identifier'
I am actually giving B as Alias name to my CTE but it is throwing error. Please help in rectifying the error. Please see the below code:
INSERT INTO ezlabor_final_ak(BREAK_TIME,DIFF_IN_OUT)
SELECT BREAK_TIME,DIFF_IN_OUT FROM (
WITH CTE_RN
AS
(
SELECT t.out_time,t.in_time,t.Employee,
ROW_NUMBER() OVER(ORDER BY In_Time) AS RN
FROM ezlabor_final_ak t
WHERE employee = 'JHW004605' AND TO_CHAR(in_time, 'dd/mm/yyyy') = '21/11/2013'
)
SELECT
a.Employee,TO_CHAR(a.in_time,'dd/mm/yyyy hh:mi:ss'),TO_CHAR(a.out_time,'dd/mm/yyyy hh:mi:ss'),a.RN as ARN,
TO_CHAR(p.out_time,'dd/mm/yyyy hh:mi:ss'),TO_CHAR(p.in_time,'dd/mm/yyyy hh:mi:ss'),p.RN AS PRN,
(a.in_time - p.out_time)*24*60 AS BREAK_TIME,
(a.OUT_TIME - a.IN_TIME)*24*60 AS DIFF_IN_OUT
FROM CTE_RN a
LEFT JOIN CTE_RN p
ON p.EMPLOYEE = a.EMPLOYEE AND
p.RN = a.RN - 1
WHERE a.employee = 'JHW004605' AND TO_CHAR(a.in_time, 'dd/mm/yyyy') = '21/11/2013'
) b
WHERE b.employee = 'JHW004605' AND TO_CHAR(b.in_time, 'dd/mm/yyyy') = '21/11/2013'

How to use 'EXIST' in a simple oracle query

I have a table called ‘MainTable’ with following data
Another table called ‘ChildTable’ with following data (foreighn key Number)
Now I want to fetch those records from ‘ChildTable’ if there exists at least one ‘S’ status.
But if any other record for this number id ‘R’ then I don’t want to fetch it
Something like this-
I tried following
Select m.Number, c.Status from MainTable m, ChildTable c
where EXISTS (SELECT NULL
FROM ChildTable c2
WHERE c2.status =’S’ and c2.status <> ‘R’
AND c2.number = m.number)
But here I am getting record having ‘R’ status also, what I am doing wrong?
You can try something like this
select num, status
from
(select id, num, status,
sum(decode(status, 'R', 1, 0)) over (partition by num) Rs,
sum(decode(status, 'S', 1, 0)) over (partition by num) Ss
from child_table) t
where t.Rs = 0 and t.Ss >= 1
-- and status = 'S'
Here is a sqlfiddle demo
The child records with 'R' might be associated with a maintable record that also has another child record with status 'S' -- that is what your query is asking for.
Select
m.Number,
c.Status
from MainTable m
join ChildTable c on c.number = m.number
where EXISTS (
SELECT NULL
FROM ChildTable c2
WHERE c2.status =’S’
AND c2.number = m.number) and
NOT EXISTS (
SELECT NULL
FROM ChildTable c2
WHERE c2.status =’R’
AND c2.number = m.number)
WITH ChildrenWithS AS (
SELECT Number
FROM ChildTable
WHERE Status = 'S'
)
,ChildrenWithR AS (
SELECT Number
FROM ChildTable
WHERE Status = 'R'
)
SELECT MaintTable.Number
,ChildTable.Status
FROM MainTable
INNER JOIN ChildTable
ON MainTable.Number = ChildTable.Number
WHERE MainTable.Number IN (SELECT Number FROM ChildrenWithS)
AND MainTable.Number NOT IN (SELECT Number FROM ChildrenWithR)

Sql recursive error invalid column name CTE

I have done following CTE it works fine,but I need to get sum of the last node so the problem is when I add T1.Debit Column to be calculated its give me an invalid column name 'Debit' !!! on line ***
ALTER Function [dbo].[SubTopics_GetSum]
-- Add the parameters for the stored procedure here
(
#TopicID int
)
RETURNS TABLE
AS
RETURN
(
-- Add the SELECT statement with parameter references here
WITH cte
AS (
SELECT
T1.TopicID,
T1.Code,
T1.Description,
T1.ParentID,
T1.ParentID AS NewParentID,
CAST(T1.Code AS nvarchar(MAX)) AS TopicCode,
CAST(T1.Description AS nvarchar(MAX)) AS TopicDescription,
isnull((Accounting.DocumentDetail.Debit),0) AS Debit,
isnull((Accounting.DocumentDetail.Credit),0) AS Credit
FROM Accounting.Topics AS T1
LEFT OUTER JOIN Accounting.DocumentDetail
ON T1.TopicID = Accounting.DocumentDetail.TopicFK
where NOT EXISTS(
SELECT
T2.TopicID,
T2.Code,
T2.Description,
T2.ParentID,
isnull((Accounting.DocumentDetail.Debit),0) AS Debit,
isnull((Accounting.DocumentDetail.Credit),0) AS Credit
FROM Accounting.Topics AS T2
LEFT OUTER JOIN Accounting.DocumentDetail
ON T2.TopicID = Accounting.DocumentDetail.TopicFK
WHERE (ParentID = T1.TopicID)
)
UNION ALL
SELECT
c.TopicID,
c.Code,
c.Description,
c.ParentID,
T1.ParentID AS NewParentID,
CAST(T1.Code AS nvarchar(MAX)) + c.TopicCode AS TopicCode,
CAST(T1.Description AS nvarchar(MAX)) + ' - ' + c.TopicDescription AS TopicDescription,
*** isnull((T1.Debit),0)+isnull(c.Debit,0) AS Debit,--IN THIS LINE error 'Invalid Column Name 'Debit''
isnull(c.Credit,0) AS Credit
FROM cte AS c
INNER JOIN Accounting.Topics AS T1
ON T1.TopicID = c.NewParentID
)
SELECT isnull(sum(Debit),0)AS Debit,
isnull(sum(Credit),0)AS Credit
FROM cte AS c
WHERE (NewParentID = #TopicID)
)
let me know whats wrong with my code confused !!!
actually it doesn't return me a last node sum of debit,credit ... !!!
check following pic
I think below code will help,
ALTER FUNCTION [dbo].[Subtopics_getsum]
-- Add the parameters for the stored procedure here
(#TopicID INT)
returns TABLE
AS
RETURN (
-- Add the SELECT statement with parameter references here
WITH cte
AS (SELECT T1.topicid,
T1.code,
T1.description,
T1.parentid,
T1.parentid AS
NewParentID
,
Cast(T1.code AS NVARCHAR(max))
AS TopicCode,
Cast(T1.description AS NVARCHAR(max)) AS
TopicDescription,
Isnull(( accounting.documentdetail.debit ), 0) AS Debit,
Isnull(( accounting.documentdetail.credit ), 0) AS Credit
FROM accounting.topics AS T1
LEFT OUTER JOIN accounting.documentdetail
ON T1.topicid =
accounting.documentdetail.topicfk
WHERE NOT EXISTS(SELECT T2.topicid,
T2.code,
T2.description,
T2.parentid,
Isnull(( accounting.documentdetail.debit ), 0)
AS
Debit,
Isnull(( accounting.documentdetail.credit ), 0) AS
Credit
FROM accounting.topics AS T2
LEFT OUTER JOIN accounting.documentdetail
ON T2.topicid =
accounting.documentdetail.topicfk
WHERE ( parentid = T1.topicid )))
SELECT Isnull(Sum(debit), 0) AS Debit,
Isnull(Sum(credit), 0)AS Credit
FROM cte AS c
WHERE ( newparentid = #TopicID )
)
I think you Accounting.Topics hasn't column Debit.
UPDTAE
isnull((T1.Debit),0)+isnull(c.Debit,0) AS Debit,--IN THIS LINE error 'Invalid Column Name 'Debit''
isnull(c.Credit,0) AS Credit
FROM cte AS c
INNER JOIN Accounting.Topics AS T1
ON T1.TopicID = c.NewParentID
In the code above your T1.Debit refers to Accounting.Topics.

Resources