anyone please help me i have procedure in oracle when the procedure is run table Rekon its get data from another table to create data, but the problem is when the data is null(empty) in another table in Table Rekon it's null but i want still have data in my Rekon table, example for template:
NO_ACC|ttrx|Amount
1111 |USD |2200
|SGD |5410
|total|7610
but when the data in another table is null in where clause substr(NARATION,1,3)='SGD'
the table its like:
NO_ACC|ttrx|Amount
1111 |USD |2200
|total|2200
it's my query:
insert into datamart.rekon_801_ugm_sm
select to_char(no_acc) no_acc, 'USD' ttrx, sum(amount) amount from (select
* from rekon_801_ugm where no_acc = 1111 and substr(narasi,9,4)='1112'
or substr(narasi,37,4)='1112') group by no_acc
union all
select to_char(no_acc) no_acc, 'SGD' as ttrx, sum(amount) amount from (select
* from rekon_801_ugm where no_acc = 8010000487 and substr(narasi,9,2)='88'
or substr(narasi,37,2)='88') group by no_acc
union all
select ' ' as no_acc, 'TOTAL TRANSAKSI H2H' as ttrx, sum(amount) amount from (select
* from rekon_801_ugm where no_acc = 1111 and debet_kredit = 'K') group by no_acc
You are using acc_no with a constant condition in all sub queries
if you want to have null values you must replace this condition with something like
(acc_no=8010000487 or acc_no is null)
Related
I have a table:
SELECT aaa.sr_nbr,
aaa.inst_nbr,
bb.country,
bb.sr_control_type,
bb.it_tran_code,
ccc.cust_name,
ccc.cust_nbr
FROM tablea1 aaa
INNER JOIN tablea2 bb
ON aaa.inst_id=bb.inst_id AND aaa.item_id=bb.item_id
LEFT JOIN table3 ccc
ON bb.inst_id=ccc.inst_id AND bb.item_id=ccc.item_id
WHERE ccc.cust_name NOT LIKE '%EXP%'
AND ccc.cust_name NOT LIKE '%RMAA%' mt;
Now, I have created, separately, queries for metrics, like:
SELECT mt.sr_nbr,
mt.inst_nbr,
mt.country,
mt.sr_control_type,
mt.it_tran_code,
mt.cust_name,
mt.cust_nbr
COUNT(mt.sr_nbr) as cnt_nbr
FROM mt
WHERE mt.it_tran_code <> 'D'
GROUP BY 1,2,3,4,5,6,7;
or the another one:
SELECT t_2.sr_nbr,
t_2.inst_nbr,
t_2.country,
t_2.sr_control_type,
t_2.it_tran_code,
t_2.cust_name,
t_2.cust_nbr
SUM(t_2.sn_dup) AS sn_dup_sum
FROM (
SELECT
t_1.sr_nbr,
t_1.inst_nbr,
t_1.country,
t_1.sr_control_type,
t_1.it_tran_code,
t_1.cust_name,
t_1.cust_nbr
COUNT(t_1.sr_nbr) AS sn_dup
FROM
(
SELECT
mt.sr_nbr,
mt.inst_nbr,
mt.country,
mt.sr_control_type,
mt.it_tran_code,
mt.cust_name,
mt.cust_nbr
FROM mt
WHERE ccc.cust_name NOT LIKE '%EXP%'
AND ccc.cust_name NOT LIKE '%RMAA%'
) AS t_1
GROUP BY 1,2,3,4,5,6,7
HAVING
COUNT(t_1.sr_nbr) > 1
) AS t_2
GROUP BY 1,2,3,4,5,6,7;
and so on... I have about 10 similar metrics.
Now, I do not know the best way how to "put" those query metrics within the main table/query.
You can insert results of a SELECT query into a table if you are able to fill the INSERT statement correctly.
Example:
INSERT INTO Customers (CustomerName, City, Country)
SELECT SupplierName, City, Country FROM Suppliers
WHERE Country='Germany';
Source: https://www.w3schools.com/sql/sql_insert_into_select.asp
Make sure the amount and types of the results matches the columns you're trying to insert.
I have a table where I'm trying to find a set of particular records. Here's what my table looks like...
tblA
ID VouchID Action Amount
1 177-17 Add 700
2 177-17 Update 1
3 198-01 Add 600
4 198-01 Update 620
So what happens here, is if a record was canceled/deleted, the action would be 'Update' and Amount would be updated to 1. In other words, the VouchID = 177-17, would not be counted/be selected in this query...
What I'm hoping to do here is only select records, that don't have a corresponding Update record with Amount = 1
Select distinct vouchID where Action='add'
However, this query does not take under consideration VoucherID's that have an 'update' action. Update action can be applied in two instances, in VouchID 177-17 the amount = 1 on action='update' that means, that the ADD action does not count, it's almost as if we removed the record all together (it's just there for record keeping). Another Update in case of VoucherID = 198-01, the update line and amount = 620, means that the Amount was updated by 20 to 620, that record i hope to be able to see in my end reuslt
Desired end result from above table:
ID VouchID Action Amount
3 198-01 Add 600
You could use LEAD (SQL Server 2012 and above):
WITH cte AS (
SELECT *, LEAD(Amount) OVER(PARTITION BY VouchID ORDER BY ID) AS next_amount
FROM table
)
SELECT *
FROM cte
WHERE (next_amount <> 1 OR next_amount IS NULL) AND Action='add';
EDIT
non-recursive CTE can be always replaced with simple subquery:
SELECT *
FROM (SELECT *,
LEAD(Amount) OVER(PARTITION BY VouchID ORDER BY ID) AS next_amount
FROM table) sub
WHERE (next_amount <> 1 OR next_amount IS NULL) AND Action='add';
EDIT:
Using EXISTS:
SELECT *
FROM table t1
WHERE Action='add'
AND NOT EXISTS (SELECT TOP 1
FROM table t2
WHERE t1.VouchId = t2.VouchId
AND Action='Update'
AND Amount = 1
ORDER BY ID ASC);
What I'm hoping to do here is only select records, that don't have a
corresponding Update record with Amount = 1
Seems easy enough with NOT EXISTS():
Select distinct vouchID FROM MyTable t1 where Action='add'
AND NOT EXISTS(SELECT * FROM MyTable t2
WHERE Action='Update'
AND Amount=1
AND t2.VouchId=t1.VouchId
Are you using SQL Server 2008 or better? If you are, I would try something like :
SELECT
ID, vouchID, Action, Amount
FROM tblA s
WHERE
Action='add'
AND NOT EXISTS(Select 1 from tblA l where l.vouchID = s.vouchID and l.Action = 'Update' and l.Amount = 1);
situation:
we have monthly files that get loaded into our data warehouse however instead of being replaced with old loads, these are just compiled on top of each other. the files are loaded in over a period of days.
so when running a SQL script, we would get duplicate records so to counteract this we run a union over 10-20 'customers' and selecting Max(loadID) e.g
SELECT
Customer
column 2
column 3
FROM
MyTable
WHERE
LOADID = (SELECT MAX (LOADID) FROM MyTable WHERE Customer= 'ASDA')
UNION
SELECT
Customer
column 2
column 3
FROM
MyTable
WHERE
LOADID = (SELECT MAX (LOADID) FROM MyTable WHERE Customer= 'TESCO'
The above union would have to be done for multiple customers so i was thinking surely there has to be a more efficient way.
we cant use a MAX (LoadID) in the SELECT statement as a possible scenario could entail the following;
Monday: Asda,Tesco,Waitrose loaded into DW (with LoadID as 124)
Tuesday: Sainsburys loaded in DW (with LoadID as 125)
Wednesday: New Tesco loaded in DW (with LoadID as 126)
so i would want LoadID 124 Asda & Waitrose, 125 Sainsburys, & 126 Tesco
Use window functions:
SELECT t.*
FROM (SELECT t.*, MAX(LOADID) OVER (PARTITION BY Customer) as maxLOADID
FROM MyTable t
) t
WHERE LOADID = maxLOADID;
Would a subquery to a derived table meet your needs?
select yourfields
from yourtables join
(select customer, max(loadID) maxLoadId
from yourtables
group by customer) derivedTable on derivedTable.customer = realTable.customer
and loadId = maxLoadId
I have an SQL script in oracle which is almost complete but I am stuck on one last issue.
I have 2 database tables I am accessing data from, and inserting the new rows into a new table in my database.
One of the database tables has an account number column and a descriptor column, and each account number has 3 descriptor values, all with the same format. There is a third column as well which I want to grab data from. Here is a visual:
Account # | Descriptor | Value
1 Cost Center: ASDF CC123
1 Company: ASDF123 F123
1 Fund: JKL R123
2 Cost Center: ASDF12 CC456
2 Company: ASDF456 F456
2 Fund: JKL23 R456
I would like my final table to be like this:
Account_Number | Company_Description | Cost_Center_Value
1 Company: ASDF123 CC123
2 Company: ASDF456 CC456
The elements for the Cost_Center_Value column and the Company_Description column come from different rows, but the same account object.
The issue I am having is that I have a special where clause to help me extract only the descriptor row with the 'Company:' text. If I put in an AND, the table is not populated at all, I think because it expects the data to be in the same row, when I want data from 2 rows but different columns. If I use and OR statement, it adds an entire new row.
Here is my script:
create table mydb.test1 as
select distinct substr(testdb.table1.FAO, 1) as Account_Number,
'CM' || substr(testdb.table1.DESCRIPTOR, 18) as Division,
substr(testdb.table1.value, 1) as Department,
substr(testdb.table2.Workday_Description, 1) as Description,
from testdb.table1
join testdb.table2
on testdb.table1.fao = testdb.table2.workday_number
where testdb.table2.descriptor like 'Company for%'
OR testdb.table1.value like 'CC%'
order by Account_Number Desc
I left the OR statement in there to show what I have been playing around with.
That is the closest I can get.
If more info is needed, let me know.
The real answer is to learn about normal form and redesign this database. However you could do something hideous like:
Select
Account_Number,
max(Case
When Descriptor Like 'Company: %' then substr(Descriptor, 10, 1000)
end) Company_Description,
max(Case
When Descriptor Like 'Cost Center: %' then value
end) Cost_Center_Value
From
test -- this is the table in the example section
Group By
Account_Number
Example SQLFiddle
You could create a subquery, which selects only the account number and Cost Center value of each account, and then query that.
This is not perfect, but it might give you an idea of what I'm thinking:
create table mydb.test1 as
select distinct substr(testdb.table1.FAO, 1) as Account_Number,
'CM' || substr(testdb.table1.DESCRIPTOR, 18) as Division,
substr(testdb.table1.value, 1) as Department,
substr(testdb.table2.Workday_Description, 1) as Description,
from testdb.table1
join (
select [ACCOUNT], [COST_CENTER_VALUE]
from [TABLE]
where Descriptor LIKE 'Cost Center%') a
on a.account_number = table1.account_number
try this query:
create table mydb.test1 as
select distinct
account as Account_Number,
(select (case when t2.Description like 'Company%' then t2.description end) from testdb.table1 t2 where t1.account=t2.account and
case when t2.Description like 'Company%' then t2.description end is not null)as Company_Description ,
(select (case when t2.Description like 'Cost Center%' then t2.value end) from testdb.table1 t2 where t1.account=t2.account and
case when t2.Description like 'Cost Center%' then t2.value end is not null)as Cost_Center_Value
from testdb.table1 t1;
I am looking for a query that performs sum operation on the all the rows except one. It will be more clear by the example below..
Suppose i have a company table like this
Company_name Rev order
c1 100 1000
c2 200 2000
c3 300 1500
now the query should insert into a table like the way explained below:
c1(rev) c1(order) sum of other(rev) other(order)
100 1000 500(sum of c2 and c3) 3500(sum of c2 and c3's order)
What would be the query for this kind of scenario?
I was thinking of a query:
insert into table_name (c1_rev,c1_order,sum_rev,sum_order)
select rev, order, sum(rev), sum(order) where Company_name=c1 ....
but I got stuck as I can not find the sum of other two using this.
In SQL server, you could do something like this to fetch the data:
WITH totals AS
(SELECT SUM(rev) revSum, SUM(ORDER_) orderSum
FROM T)
SELECT company_name,
rev,
order_,
totals.revsum - rev AS otherRev,
totals.orderSum - order_ AS otherOrder
FROM t, totals
Try this query:
SELECT Company_name ,
Rev ,
ORDER,
(SELECT SUM(Rev ) FROM table_name k WHERE k.Company_name<>t.Company_name
)"sum of other(rev)",
(SELECT SUM(order ) FROM table_name k WHERE k.Company_name<>t.Company_name
)"other(order)"
FROM table_name t
In Hive, a query similar to:
select sq.cnn,sum(rev),sum(orders) from
(select if(cn=='c1','c1','other') as cnn, rev,orders from test_cn) sq
group by sq.cnn;
will generate 2 rows :
c1 100 1000
other 500 3500
Doesn't exactly match your output, but can extract in a form you need.
To test, create a text file with the following:
% cat test_cn
c1|100|1000
c2|200|2000
c3|300|3000
and in hive:
hive> drop table if exists test_cn;
hive> create table test_cn (cn string, rev int, orders int) row format delimited fields terminated by '|' stored as textfile;
hive> select sq.cnn,sum(rev),sum(orders) from (select if(cn=='c1','c1','other') as cnn, rev,orders from test_cn)sq group by sq.cnn;
Having without Group By would be the best solution but HIVE dosen't suport it for now, try this:
insert into table table_name
select rev, order, sumRev, sumOrd
from (
select Company_name,rev, order, sum(rev)-rev as sumRev, sum(order) - order as sumOrd from base_table
) a
where Company_name='c1'