Extract selective records - sql

I have a table like this:
Table A
Customer InvoiceNo Region Type Amount
A001 10001 Europe FG 100
B001 10002 Asia FG 200
C001 10003 America MISC 50
D001 10004 Asia FG 300
A001 10005 Europe MISC 20
C001 10006 America MISC 10
B001 10007 Asia FG 300
I wish to split the Amount into 2 columns, namely Sales_Amt & Misc. The Region is not required.
The result that I wish to have should look like this:
Customer InvoiceNo Type Sales_Amt MISC
A001 10001 FG 100 0
B001 10002 FG 200 0
C001 10003 MISC 0 50
D001 10004 FG 300 0
A001 10005 MISC 0 20
C001 10006 MISC 0 10
B001 10007 FG 300 0
Thanks.

That's pretty simple:
select
Customer,
InvoiceNo,
Type,
decode(Type, 'MISC', 0, 1) * Amount as Sales_Amt,
decode(Type, 'MISC', 1, 0) * Amount as Misc
from
TableA
;

Select Customer,InvoiceNo,Type,
Case when TYPE!='MISC' Then amount Else 0 End as Sales_Amt,
Case when TYPE='MISC' Then amount Else 0 End as Misc
From TabalA

Related

How to create a categorical variable using union in SQL?

If I have data like...
user_id user_revenue
10000 100
10001 150
10002 175
10003 200
10004 250
10005 300
10006 400
10007 500
10007 550
I'm trying to transform the data into this using union:
user_id user_revenue
10000 Low
10001 Low
10002 Low
10003 Medium
10004 Medium
10005 Medium
10006 High
10007 High
10007 High
Where "High" is when revenue is at least 400 and "medium" is less than 400 but greater than 175 then low is when the revenue is at most 175.
This is simple CASE statement on user_revenue
SELECT user_id,
CASE
WHEN t.user_revenue > 400 THEN 'High'
WHEN t.user_revenue > 175 THEN 'Medium'
ELSE 'Low'
END AS user_revenue
FROM [Table] t;

How to statistics sales, city, customer of goods use oracle

I have a oracle view, and include the sale of goods details. It like this:
OrderId OrderDetailId GoodsId GoodsName UnitName SalesQty Price CustomerName Country City
200138 ddd0a3b42adb 770 A bag 5 18.00 AAAA USA NewYork
223448 70ca7ceb41c7 193 D bottle 10 10.00 BBB USA NewYork
200118 ab472857573e 1286 F cup 8 50.00 CCC China Beijing
244028 230a43920667 770 A bag 20 18.00 CCC China Beijing
251118 118fc2b3839b 5929 C box 40 6.00 DDDD Japan Tokyo
200000 abd0a3b42ddd 770 A bag 15 18.00 AAAA USA NewYork
111118 11111113839b 5929 C box 40 6.00 FFFF Japan Tokyo
And I want a SQL statement statistics sales, the number of cities, the number of customers of each goods. The result should be like this:
GoodsId GoodsName SalesQty(UnitName) CityQty CustomerQty
GoodsId GoodsName SalesQty(UnitName) CityQty CustomerQty
770 A 40(bag) 2 2
193 D 10(bottle) 1 1
1286 F 8(cup) 1 1
5929 C 80(box) 1 2
How to write sql statistical statement? Thanks!
Simply use GROUP BY
select GoodsId, GoodsName, UnitName,
sum(SalesQty) SalesQty,
count(distinct City) CityQty,
count(distinct CustomerName) CustomerQty
from goods_view
group by GoodsId, GoodsName, UnitName
demo
You may use cube, to include also sub&grand totals of quantities :
select GoodsId, GoodsName||'('||UnitName||')' GoodsName,
sum(SalesQty) SalesQty, count(distinct City) CityQty, count(distinct CustomerName) CustomerQty
from v_goods
group by cube(GoodsId, GoodsName||'('||UnitName||')')
order by GoodsId,GoodsName||'('||UnitName||')';

Stored Procedure Select from 3 tables

I have three tables in my database Sales, SalesPeople and Appliances.
Sales
SaleDate EmployeeID AppID Qty
---------- ---------- ----- -----------
2010-01-01 1412 150 1
2010-01-05 3231 110 1
2010-01-03 2920 110 2
2010-01-13 1412 100 1
2010-01-25 1235 150 2
2010-01-22 1235 100 2
2010-01-12 2920 150 3
2010-01-14 3231 100 1
2010-01-15 1235 300 1
2010-01-03 2920 200 2
2010-01-31 2920 310 1
2010-01-05 1412 420 1
2010-01-15 3231 400 2
SalesPeople
EmployeeID EmployeeName CommRate BaseSalary SupervisorID
---------- ------------------------------ ----------- ----------- ------------
1235 Linda Smith 15 1200 1412
1412 Anne Green 12 1800 NULL
2920 Charles Brown 10 1150 1412
3231 Harry Purple 18 1700 1412
Appliances
ID AppType StoreID Cost Price
---- -------------------- ------- ------------- -------------
100 Refrigerator 22 150 250
110 Refrigerator 20 175 300
150 Television 27 225 340
200 Microwave Oven 22 120 180
300 Washer 27 200 325
310 Washer 22 280 400
400 Dryer 20 150 220
420 Dryer 22 240 360
How can I obtain this result? (That displays the profitability of each of the salespeople ordered from the most profitable to the least. Gross is simply the sum of the quantity of items sold multiplied by the price. Commission is calculated from the gross minus the cost of those items (i.e. from
qty*(price-cost)). Net profit is the total profit minus commission.)
Name Gross Commission Net Profit
------------- ----- ---------- ---------
Charles Brown 2380 83.5 751.5
Linda Smith 1505 83.25 471.75
Harry Purple 990 65.7 299.3
Anne Green 950 40.2 294.8
My attempt:
CREATE PROC Profitability AS
SELECT
sp.EmployeeName, (sum(s.Qty) * a.Price) as [Gross],
[Gross] - a.Cost, as [Commision],
SOMETHING as [Net Profit]
FROM
Salespeople sp, Appliances a, Sales s
WHERE
s.AppID = a.ID
AND sp.EmployeeID = s.EmployeeID
GROUP BY
sp.EmployeeName
GO
EXEC Profitability
Simple rule: Never use commas in the FROM clause. Always use explicit JOIN syntax.
In addition to fixing the JOIN syntax, your query needs a few other enhancements for the aggregation functions:
SELECT sp.EmployeeName, sum(s.Qty * a.Price) as Gross,
SUM(s.Qty * (a.Price - a.Cost)) * sp.CommRate / 100.0 as Commission,
SUM(s.Qty * (a.Price - a.Cost)) * (1 - sp.CommRate / 100.0) as NetProfit
FROM Sales s JOIN
Salespeople sp
ON sp.EmployeeID = s.EmployeeID JOIN
Appliances a
ON s.AppID = a.ID
GROUP BY sp.EmployeeName sp.CommRate
ORDER BY NetProfit DESC;

Incremental count in SQL Server 2005

I am working with a Raiser's Edge database using SQL Server 2005. I have written SQL that will produce a temporary table containing details of direct debit instalments. Below is a small table containing the key variables for the question I'm going to ask, with some fictional data:
Donor_ID Instalment_ID Instalment_Date Amount
1234 1111 01/01/2011 £5.00
1234 1112 01/02/2011 £0.00
1234 1113 01/03/2011 £5.00
1234 1114 01/04/2011 £5.00
1234 1115 01/05/2011 £0.00
1234 1116 01/06/2011 £0.00
2345 2111 01/01/2011 £0.00
2345 2112 01/02/2011 £5.00
2345 2113 01/03/2011 £5.00
2345 2114 01/04/2011 £0.00
2345 2115 01/05/2011 £0.00
2345 2116 01/06/2011 £0.00
As you will see, some of the values in the Amount column are £0.00. This can occur when a donor has insufficient funds in their account, for example.
What I'd like to do is write a SQL query that will create a field containing an incremental count of consecutive £0.00 payments that resets after a non-£0.00 payment or after a change in Donor_ID. I have reproduced the above data below, with the field I'd like to see.
Donor_ID Instalment_ID Instalment_Date Amount New_Field
1234 1111 01/01/2011 £5.00
1234 1112 01/02/2011 £0.00 1
1234 1113 01/03/2011 £5.00
1234 1114 01/04/2011 £5.00
1234 1115 01/05/2011 £0.00 1
1234 1116 01/06/2011 £0.00 2
2345 2111 01/01/2011 £0.00 1
2345 2112 01/02/2011 £5.00
2345 2113 01/03/2011 £5.00
2345 2114 01/04/2011 £0.00 1
2345 2115 01/05/2011 £0.00 2
2345 2116 01/06/2011 £0.00 3
To help clarify what I'm looking for, I think what I'm looking to do would be similar to a winning streak field on a list of a football team's results. For example:
Opponent Score Winning_Streak
Arsenal 1-0 1
Liverpool 0-0
Swansea 3-1 1
Chelsea 2-1 2
Fulham 4-0 3
Stoke 0-0
Man Utd 1-3
Reading 2-1 1
I've considered various options, but have made no progress. Unless I've missed something obvious, I think that a solution more advanced than my current SQL programming level might be required.
If I am thinking about this problem correctly, I believe that you want a row number when the Amount is 0.00 pounds.
Select 0 as As InsufficientCount
, Donor_ID
, Installment_ID
, Amount
From [Table]
Where Amount > 0.00
Union
Select Row_Number() Over (Partition By Donor_ID Order By Installment_ID)
, Donor_ID
, Installment_ID
, Amount
From [Table]
Where Amount = 0.00
This union select should only give you 'ranks' where the Amount equals 0.
Am calling your new field streakAmount
ALTER TABLE instalments ADD streakAmount int NULL;
Then, to update the value:
UPDATE instalments
SET streakAmount =
(SELECT
COUNT(*)
FROM
instalments streak
WHERE
streak.donor_id = instalments.donor_id
AND
streak.instalment_date <= instalments.instalment_date
AND
(streak.instalment_date >
-- find previous instalment date, if any exists
COALESCE(
(
SELECT
MAX(instalment_date)
FROM
instalments prev
WHERE
prev.donor_id = instalments.donor_id
AND
prev.amount > 0
AND
prev.instalment_date < instalments.instalment_date
)
-- otherwise min date
, cast('1753-1-1' AS date))
)
)
WHERE
amount = 0;
http://sqlfiddle.com/#!6/a571f/18

Complicated Sql Query Of Joining Two Tables

I having Following Two Tables and wants the result date and bank wise. The Example is as below.
Table1: Name:- AccountMast
companyID A/CID Name BalDR BalCR
102 14 SHOBHA NULL NULL
102 15 SONKI NULL NULL
102 16 BANK OF INDIA null 12000
Table2 Name :- DeBank
companyID transID date name particulars deposit withdrawal
102 2 12/04/2012 BANK OF INDIA MAHENDRA 1000 NULL
102 4 15/04/2012 CENTRAL BANK MAHENDRA 1000 NULL
102 3 20/05/2012 BANK OF INDIA MAHENDRA 2000 NULL
Result
BANK WISE RESULT BANK OF INDIA
date transID particulars deposit withdrawal BALANCE
01/04/2012 BAL B/F 12000
12/04/2012 2 MAHENDRA 1000 NULL 13000
20/05/2012 3 MAHENDRA 2000 NULL 15000
BANK WISE RESULT CENTRAL BANK OF INDIA
date transID particulars deposit withdrawal BALANCE**
01/04/2012 BAL B/F
15/04/2012 4 MAHENDRA 2000 NULL 2000
So what is the sql statement for it?.