Need a SQL insert query for a table from a temporary table without duplication - sql

I need to insert into a table from a temporary table without duplicating the data from temp table. ie , for each customer need to insert a single row with SpecialCreditNoteAwarded
My temporary table:
CustID SalesMasterID SpecialCreditNoteAwarded
------------------------------------------------
100 13139 92115
100 13148 92115
100 13150 92115
101 13204 1175
101 13205 1175
102 13209 650
102 13210 650
102 13211 650
Result table
CustID SaleID SpecialCreditNoteAwarded
-----------------------------------------
100 0 92115
101 0 1175
102 0 650

You can use the GROUP BY function in a SELECT statement to remove duplicates
INSERT INTO Table_rslt (CustID, SaleID, SpecialCreditNoteAwarded)
SELECT
CustID
,0
,SpecialCreditNoteAwarded
FROM #temp
GROUP BY CustID,SpecialCreditNoteAwarded;
You didn't specify your DBMS, so this answer is for SQL SERVER.

Related

More than one occurrence from table

create table customer (cif number, name varchar(20),mobile number);
insert into table customer values(121,'ANT',789);
insert into table customer values(122,'ANT',789);
insert into table customer values(123,'ENT',789);
insert into customer values(124,'ENT',789);
insert into customer values(125,'BEE',123);
insert into customer values(126,'BEE',123);
insert into customer values(127,'BRO',789);
insert into customer values(128,'FIO',789);
commit;
I want retrieve data from customer table based on name and mobile more than one occurrences.
Can anyone help me out
Result like
You can use COUNT() aggregation as Analytic function along with grouping by those columns through use of PARTITION BY clause as
SELECT cif, name, mobile
FROM (SELECT c.*,
COUNT(*) OVER (PARTITION BY name, mobile) AS cnt
FROM customer c )
WHERE cnt > 1
Demo
Source:
SQL> select * From customer;
CIF NAME MOBILE
---------- -------------------- ----------
121 ANT 789
122 ANT 789
123 ENT 789
124 ENT 789
125 BEE 123
126 BEE 123
127 BRO 789
128 FIO 789
8 rows selected.
Based on result you posted, you're looking for rows that aren't unique per name and mobile. If that's so, here's another option:
SQL> select *
2 from customer a
3 where exists (select null
4 from customer b
5 where b.name = a.name
6 and b.mobile = a.mobile
7 group by b.name, b.mobile
8 having count(*) > 1
9 );
CIF NAME MOBILE
---------- -------------------- ----------
121 ANT 789
122 ANT 789
123 ENT 789
124 ENT 789
125 BEE 123
126 BEE 123
6 rows selected.
SQL>

How do I return a key value when a specific column value is NOT present?

Here's a simplified example of my SALESORDERLINES table:
ORDER
LINE
ITEM
100
1
ITEMA
100
2
ITEMB
100
3
FEE
101
1
ITEMA
101
2
FEE
102
1
ITEMC
102
2
ITEMD
102
3
ITEME
103
1
ITEMA
103
2
FEE
104
1
ITEMB
104
2
ITEMC
The key values for the table are ORDER and LINE.
The last line item of each order is supposed to be item "FEE", but occasionally order entry forgets to include it. I'm trying to find every instance where they failed to include the fee on the order.
So for the example data above, I would want to return order numbers 102 and 104 only.
Any ideas?
Just a guess since you don't specify what resultset you desire. And surely there is another table that you did not include that represents "orders" - perhaps named SALESORDERS?
Assuming that, then I suggest:
select ord."ORDER" -- a terrible idea to use reserved words as names
from dbo.SALESORDERS as ord
where not exists (select * from dbo.SALESORDERLINES as ordlines
where ord."ORDER" = ordlines."ORDER" and ordlines.ITEM = 'FEE')
order by ...;
Certainly there are other ways. EXCEPT comes to mind.
Try this :
SELECT ORDER
FROM TableA
WHERE ORDER NOT IN (
SELECT ORDER
FROM TableA
WHERE ITEM = 'FEE'
GROUP BY ORDER)
GROUP BY ORDER

SQL DB2 Toad - Sum from two tables by ID

I was hoping to find the sum from two tables with columns ID and Amount, grouping by ID.
My first attempt was to UNION the two tables first and then conduct a sum and group by, but I was hoping to know of a better way.
Inputs:
Table 1
ID Amount
123 100
123 100
145 500
167 600
Table 2
ID Amount
123 100
123 100
145 500
199 600
Output
ID Amount
123 400
145 1000
167 600
199 600
You can do:
select id, sum(amount) as amount
from (
select id, amount from table_1
union all
select id, amount from table_2
) x
group by id

Dividing a sum value into multiple rows due to field length constraint

I am migrating financial data from a very large table (100 million+ of rows) by summarizing the amount and insert them into summary table. I ran into problem when the summary amount (3 billions) is larger than what the field in the summary table can hold (can only hold up to 999 millions.) Changing the field size is not an option as it requires a change process.
The only option I have is to divide the amount (the one that breach the size limit) into smaller ones so it can be inserted into the table.
I came across this SQL - I need to divide a total value into multiple rows in another table which is similar except the number of rows I need to insert is dynamic.
For simplicity, this is how the source table might look like
account_table
acct_num | amt
-------------------------------
101 125.00
101 550.00
101 650.00
101 375.00
101 475.00
102 15.00
103 325.00
103 875.00
104 200.00
104 275.00
The summary records are as follows
select acct_num, sum(amt)
from account_table
group by acct_num
Account Summary
acct_num | amt
-------------------------------
101 2175.00
102 15.00
103 1200.00
104 475.00
Assuming the maximum value in the destination table is 1000.00, the expected output will be
summary_table
acct_num | amt
-------------------------------
101 1000.00
101 1000.00
101 175.00
102 15.00
103 1000.00
103 200.00
104 475.00
How do I create a query to get the expected result? Thanks in advance.
You need a numbers table. If you have a handful of values, you can define it manually. Otherwise, you might have one on hand or use a similar logic:
with n as (
select (rownum - 1) as n
from account_table
where rownum <= 10
),
a as (
select acct_num, sum(amt) as amt
from account_table
group by acct_num
)
select acct_num,
(case when (n.n + 1) * 1000 < amt then 1000
else amt - n.n * 1000
end) as amt
from a join
n
on n.n * 1000 < amt ;
A variation along these lines might give some ideas (using the 1,000 of your sample data):
WITH summary AS (
SELECT acct_num
,TRUNC(SUM(amt) / 1000) AS times
,MOD(SUM(amt), 1000) AS remainder
FROM account_table
GROUP BY acct_num
), x(acct_num, times, remainder) AS (
SELECT acct_num, times, remainder
FROM summary
UNION ALL
SELECT s.acct_num, x.times - 1, s.remainder
FROM summary s
,x
WHERE s.acct_num = x.acct_num
AND x.times > 0
)
SELECT acct_num
,CASE WHEN times = 0 THEN remainder ELSE 1000 END AS amt
FROM x
ORDER BY acct_num, amt DESC
The idea is to first build a summary table with div and modulo:
ACCT_NUM TIMES REMAINDER
101 2 175
102 0 15
103 1 200
104 0 475
Then perform a hierarchical query on the summary table based on the number of "times" (i.e. rows) you want, with an extra for the remainder.
ACCT_NUM AMT
101 1000
101 1000
101 175
102 15
103 1000
103 200
104 475

Calculate MonthlyVolume - PIVOT SQL

I am using SQL server 2008 and I have following Table with millions of rows...Here are few sample records
Serial_Num ReadingDate M_Counter Dyn_Counter
XYZ 3/15/2014 100 190
XYZ 4/18/2014 140 240
XYZ 5/18/2014 200 380
ABC 3/12/2014 45 40
ABC 4/19/2014 120 110
ABC 5/21/2014 130 155
This table will always have only one reading for each month and no missing months....
and I would like calculate M_Counter and Dyn_Counter values for each month, For an example XYZ -> May month calculated counter value should be 60 = 200 (05/18/2014 value) - 140 (04/18/2014 value). I would like to insert data into another table in following way.
CalculatedYear CalculatedMonth Serial_Num M_Counter_Calc Dyn_Counter_Calc
2014 4 XYZ 40 50
2014 5 XYZ 60 140
2014 4 ABC 75 70
2014 5 ABC 10 45
Any help really appreciated!
If you're using MS SQL, something like this should work. The concept is to sort the dataset based on Serial_Num and ReadingDate. Add a sequential Row ID and store into a temp table. Join the table onto itself such that you match up the current row with the previous row where the serial numbers still match. If there wasn't a prior month's reading, the value will be null. We use Isnull( x, 0) to account for this when doing the calculations.
declare #Temp1 table
(
RowID int,
Serial_Num varchar(3),
ReadingDate datetime,
M_Counter int,
Dyn_Counter int
)
insert into #Temp1
select ROW_NUMBER() over (order by Serial_Num, ReadingDate), *
from MyTable T
select
Year(T1.ReadingDate) As CalculatedYear,
Month(T1.ReadingDate) as CalculatedMonth,
T1.Serial_Num,
T1.M_Counter - ISNULL(T2.M_Counter,0) as Calculated_M_Counter,
T1.Dyn_Counter - isnull(T2.Dyn_Counter,0) as Calculated_Dyn_Counter
from #Temp1 T1
left outer join #Temp1 T2 on T1.RowID = T2.RowID + 1 and T1.Serial_Num = T2.Serial_Num
order by T1.Serial_Num, Year(T1.ReadingDate), Month(T1.ReadingDate)