I have two tables one for transactions and the other for country as below :
Transaction table:
| trx_id | cust_id | cust_name
| 01 | AA01 | cust1 |
| 02 | AA02 |cust2 |
| 03 | 225 |cust1 |
country table
| cust_id|country |
| AA01 | CA |
| AA02 | NA |
after joining the 2 tables using cust_id I will have country for all customers except cust_id 225.
How to fill the null value for customer 225 if different id but same customer name with the correct country name in this example CA ,noting that I need it as calculated column in SSAS model.
Thank you
Related
I want to join two tables in Oracle and list the results concatenated if they have the same parent id in this way:
Table All
|id | other fields|service_id|
|------|-------------|----------|
| 827 |xxxxxxxx |null |
| 828 |xxxxxxxx |327 |
| 829 |xxxxxxxx |328 |
| 860 |xxxxxxxx |null |
| 861 |xxxxxxxx |326 |
Table Services
| id | parent_id |
| ---- | -------|
| 326 | 860 |
| 327 | 827 |
| 328 | 827 |
I want a query that returns this
|id | sub_id |
|------|---------|
| 827 | 828,829 |
| 828 | null |
| 829 | null |
| 860 | 861 |
| 861 | null |
Thanks a lot!
By joining the all table to service and then back to all in an alias you can get the ID and sub id's in a list that then just need to be combined from multiple rows into 1 column per ID.
This should get you the "Raw data" that then needs to be aggregrated...
TESTED: Rextester working example
NOTE: Since you have different "LEVELS" of depth for your sub_ID i'm not really sure what you want so 860 and 123 isn't included because it's a completely different field than the source of 827
SELECT A.ID as ID, A2.ID as Sub_ID
FROM ALL A
LEFT JOIN SERVICES S
on S.Pareint_ID = A.ID
LEFT JOIN All A2
on A2.Service_ID = S.ID
Now... if we assume that you have a version of oracle which supports ListAgg
SELECT A.ID as ID, ListAgg(A2.ID,',') within group (Order by A2.ID) as Sub_ID
FROM ALL A
LEFT JOIN SERVICES S
on S.Parent_ID = A.ID
LEFT JOIN All A2
on A2.Service_ID = S.ID
GROUP BY A.ID
Giving Us:
+----+-----+---------+
| | ID | SUB_ID |
+----+-----+---------+
| 1 | 827 | 828,829 | -- These are all.id's...
| 2 | 828 | NULL |
| 3 | 829 | NULL |
| 4 | 860 | NULL | --> Now why is 123 present as it's a service.id
| 5 | 861 | NULL |
+----+-----+---------+
**Note all is a reserved word and either needs to be escaped or if your table name really isn't all; adjust accordingly.
LISTAGG Docs
This question is for database oracle, I have table A which have data for one week for every hour like below
----------------------------
NAME | CODE | INSERTDATE (Timestamp- datatype)
----------------------------
YYY | Y | 11/8/2017 1:32:22.000000000 PM
zzz | Z | 11/8/2017 2:32:22.000000000 PM
aaa | A | 11/8/2017 3:32:22.000000000 PM
bbb | B | 11/8/2017 4:32:22.000000000 PM
ccc | C | 11/8/2017 5:32:22.000000000 PM
SSS | S | 11/8/2017 6:32:22.000000000 PM
... | . | ..............................
... | . | ..............................
... | . | ..............................
RRR | R | 11/8/2017 11:32:22.000000000 PM
table have data for duration of one week and I am looking to select every record after 5 hour. (so total records are 168 and I need output 168/5= 33 or 34 records) like below
For Ex
table A
----------------------------
NAME | CODE | INSERTDATE (Timestamp- datatype)
----------------------------
YYY | Y | 11/8/2017 1:32:22.000000000 PM
SSS | S | 11/8/2017 6:32:22.000000000 PM
RRR | R | 11/8/2017 11:32:22.000000000 PM
... | . | ..............................
... | . | ..............................
... | . | ..............................
Please suggest how can I get this.
Thanks
For the datatype timestamp the syntax of adding time is + INTERVAL '5' HOUR or just use the minus symbol to subtract. It may be used anywhere you need such a calculation as the following example shows:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE Table1
(NAME varchar2(3), CODE varchar2(1), INSERTDATE timestamp)
;
INSERT ALL
INTO Table1 ("NAME", "CODE", "INSERTDATE")
VALUES ('YYY', 'Y', '08-Nov-2017 01:32:22 PM')
INTO Table1 ("NAME", "CODE", "INSERTDATE")
VALUES ('SSS', 'S', '08-Nov-2017 06:32:22 PM')
INTO Table1 ("NAME", "CODE", "INSERTDATE")
VALUES ('RRR', 'R', '08-Nov-2017 11:32:22 PM')
SELECT * FROM dual
;
Query 1:
select
*
from table1 t1
left join table1 t2 on t1.INSERTDATE = (t2.INSERTDATE + interval '5' HOUR)
Results:
| NAME | CODE | t1.INSERTDATE | NAME | CODE | t2.INSERTDATE |
|------|------|-----------------------|--------|--------|-----------------------|
| SSS | S | 2017-11-08 18:32:22.0 | YYY | Y | 2017-11-08 13:32:22.0 |
| RRR | R | 2017-11-08 23:32:22.0 | SSS | S | 2017-11-08 18:32:22.0 |
| YYY | Y | 2017-11-08 13:32:22.0 | (null) | (null) | (null) |
Can someone please help me on this.
I have data like this
**id,age,name**
10,25,abc
10,35,def
20,45,ghi
20,55,jkl
20,65,mno
30,40,pqr
30,50,stu
30,70,vwr
40,20,yza
40,25,fdf
40,25,dgh
40,20,sfs
Now I want to get the final result as below
+------+------+
| id | age |
+------+------+
| 10 | 25 |
| 20 | 45 |
| 30 | 40 |
| 40 | 20 |
| 40 | 20 |
+------+------+
I am able to do this in mysql but as hive do not support multiple arguments in sub query so I am not able to get desired result in hive.
I tried doing this using hive join but no success.
Thanks in advance for help!!
select id
,age
from (select id
,age
,rank () over
(
partition by id
order by age
) as rnk
from mytable
) t
where t.rnk = 1
+----+-----+
| id | age |
+----+-----+
| 10 | 25 |
| 20 | 45 |
| 30 | 40 |
| 40 | 20 |
| 40 | 20 |
+----+-----+
Other way to implement expected output.
SELECT id,
age
FROM
(SELECT id,
age
FROM tblname) a LEFT SEMI
JOIN
(SELECT id,
MIN(age) age
FROM tblName
GROUP BY id) b ON a.id=b.id
AND a.age=b.age
I'm trying to insert some fields into MYTABLE from views MYVIEW1 and MYVIEW2 and then add a value from a parameter (this is part of a stored procedure) for UPDATED_BY, SYSDATE for UPDATED_ON. How can I correctly do this with INSERT SELECT or some other way entirely?
MYVIEW1
+------+----+-----+-----------+---------+
| YR | MO | QTR | USER_CODE | MO_PERF |
+------+----+-----+-----------+---------+
| 2012 | 1 | 1 | 1099 | 89 |
| 2012 | 2 | 1 | 1099 | 86 |
| 2012 | 3 | 1 | 1099 | 95 |
+------+----+-----+-----------+---------+
MYVIEW2
+------+-----+-----------+----------+
| YR | QTR | USER_CODE | QTR_PERF |
+------+-----+-----------+----------+
| 2012 | 1 | 1099 | 90 |
+------+-----+-----------+----------+
MYTABLE
+------+-----+-----------+---------+---------+---------+---------+-------------+------------+
| YR | QTR | USER_CODE | MO1_PCT | MO2_PCT | MO3_PCT | INC | UPDATED_BY | UPDATED_ON |
+------+-----+-----------+---------+---------+---------+---------+-------------+------------+
| 2012 | 1 | 1099 | 89 | 86 | 95 | 7000 | SAMPLE NAME | 01/16/2013 |
+------+-----+-----------+---------+---------+---------+---------+-------------+------------+
INSERT INTO MYTABLE
(YR,QTR,USER_CODE,MO1_PCT,MO2_PCT,MO3_PCT,INC,UPDATED_BY,UPDATED_ON)
SELECT b.YR,b.QTR,b.USER_CODE,b.MO1_PCT,b.MO2_PCT,b.MO3_PCT,c.INC
FROM MYVIEW1 b,
MYVIEW2 c
How do I insert values for (first month of QTR's MO_PERF) as MO1_PCT and (second month of QTR's MO_PERF) as MO2_PCT and (last month of QTR's MO_PERF) as MO3_PCT, making sure that I've inserted the right month within the right quarter and year.And then check if the MO_PERF values of each month has reached at least 85, else set INC as NULL.
,CASE WHEN MO1_PCT>=85 AND MO2_PCT>=85 AND MO3_PCT>=85 THEN 7000
ELSE NULL
END INC
If you're using oracle 11g then you can use PIVOT like this:
select YR, QTR, USER_CODE, "1_MO_PCT" MO1_PCT, "2_MO_PCT" MO2_PCT, "3_MO_PCT" MO3_PCT ,
case when "1_MO_PCT" >= 85 and "2_MO_PCT" >= 85 and "2_MO_PCT" >= 85 then 7000 end INC,
user updated_by, sysdate updated_on
from (
select m1.yr, m1.mo, m1.qtr, m1.user_code, m1.mo_perf, m2.qtr_perf
from myview1 m1 join myview2 m2 on m1.yr=m2.yr
and m1.qtr = m2.qtr and m1.user_code = m2.user_code )t
pivot(
max(mo_perf) MO_PCT for mo in (1,2,3)
)
Here is a sqlfiddle demo
I am working on a trigger which needs INSERT INTO with WHERE logic.
I have three tables.
Absence_table:
-----------------------------
| user_id | absence_reason |
-----------------------------
| 1234567 | 40 |
| 1234567 | 50 |
| 1213 | 40 |
| 1314 | 20 |
| 1111 | 20 |
-----------------------------
company_table:
-----------------------------
| user_id | company_id |
-----------------------------
| 1234567 | 10201 |
| 1213 | 10200 |
| 1314 | 10202 |
| 1111 | 10200 |
-----------------------------
employment_table:
--------------------------------------
| user_id | emp_type | emp_no |
--------------------------------------
| 1234567 | Int | 1 |
| 1213 | Int | 2 |
| 1314 | Int | 3 |
| 1111 | Ext | 4 |
--------------------------------------
and finally I have the table out where data should be going only who have emp_type = Int in employment_table and have company_id = 10200
out:
--------------------------------
| employee_id | absence_reason |
--------------------------------
| 1 | 40 |
| 1 | 50 |
| 2 | 40 |
| 3 | 20 |
--------------------------------
Here is my trigger:
CREATE OR REPLACE TRIGGER "INOUT"."ABSENCE_TRIGGER"
AFTER INSERT ON absence_table
FOR EACH ROW
DECLARE
BEGIN
CASE
WHEN INSERTING THEN
INSERT INTO out (absence_reason, employee_id)
VALUES (:NEW.absence_reason, (SELECT employee_id FROM employment_table WHERE user_id = :NEW.user_id)
WHERE user_id IN
(SELECT user_id FROM employment_table WHERE employment_type = 'INT')
AND user_id IN
(SELECT user_id FROM company_table WHERE company_id = '10200');
END CASE;
END absence_trigger;
It is obviously not working and I can't figure out what should I do to make it work. Any suggestions?
change the insert to this:
insert into out (absence_reason, employee_id)
select :NEW.absence_reason, e.emp_no
from employment_table e
inner join company_table c
on c.user_id = e.user_id
where e.user_id = :NEW.user_id
and e.emp_type = 'INT'
and c.company_id = '10200';
which should work. note you had emp_no in your sample structure yet employee_id in the trigger insert too. i've assumed emp_no is right. also emp_type vs employment_type.
Finally in your trigger you have company_id in quotes. Is it really a varchar2? if so OK, if not, don't use quotes.
The parentheses are not balanced. The one for values is not closed. This is the cause of your specific error, but #DazzaL's answer looks like the correct solution.