SQL - Function to divide value among rows - sql

I normally don't do database programming so Im rusty on how to do certain stuff. But I have an issue where I'm to take an item and if this item is in the same location but in different placements, divide the value of said item among the sum count between placements.
here is my table structure:
LOCATION PLACEMENT VALUE COUNT ITEM
25 12345 100 10 55555 <----
25 67890 100 20 55555 <----
25 11111 50 5 00000
25 22222 75 5 11111
In other words Item (55555) is in 2 placements and the value of this item is 100
The new value should be: PLACEMENT 12345 will be (10/30) *100 = 33.3 and PLACEMENT 67890 will be (20/30) * 100 = 66.7
Any idea how to do this in SQL or HQL?

create table new as
select item,count(distinct placement) as dist_placement,count(count)as count,sum(count) as s_count
from mytable
group by item,location;
hive> select * from new;
OK
00000 1 1 5
11111 1 1 5
55555 2 2 30
Create table final as
select b.location as location,b.placement as placement, CASE
WHEN a.count=2 and a.dist_placement=2 then cast(((b.count/a.s_count)*b.value) as double)
ELSE cast(b.value as double)
END , b.count as count, b.item as item
from new a
join mytable b
on a.item=b.item;
select * from final;
output
location placement value count item
25 12345 33.33333333333333 10 55555
25 67890 66.66666666666666 20 55555
25 11111 50.0 5 00000
25 22222 75.0 5 11111
if you give input with same placement and different item
LOCATION PLACEMENT VALUE COUNT ITEM
25 12345 100 10 55555 <----
25 12345 100 20 55555 <----
25 11111 50 5 00000
25 22222 75 5 11111
output will be
LOCATION PLACEMENT VALUE COUNT ITEM
25 12345 100.0 10 55555
25 12345 100.0 20 55555
25 11111 50.0 5 00000
25 22222 75.0 5 11111
May I right, let me know if you have other requirements.

There may be a more efficient way to do it, but in two steps you can add up the item_count and then create the new value by dividing it through.
create table new as select
item, sum(count) as item_count
from old
group by item, location, placement;
create table new2 as select
a.*,
b.item_count,
a.count/b.item_count as new_count
from old a
left join new b
on a.item=b.item;

Your sample table
SELECT * INTO #TEMP FROM
(
SELECT 25 LOCATION,12345 PLACEMENT,100 VALUE ,10 [COUNT], 55555 ITEM
UNION ALL
SELECT 25 , 67890 , 100 , 20,55555
UNION ALL
SELECT 25 , 11111 , 50 , 5,00000
UNION ALL
SELECT 25 , 22222 , 75 , 5, 11111
)TAB
Your result is below
SELECT *,
CAST(([COUNT]/CAST(SUM([COUNT]) OVER(PARTITION BY ITEM)AS NUMERIC(20,2)))*VALUE AS NUMERIC(20,1)) Result
FROM #TEMP

Related

incorrect Oracle order calculation logic at the query level

With online qty and str qty, I'm having trouble calculating the quantity.
I tried the data computation with one record, and it worked perfectly with online qty and str qty. However, when I attempted it with several records (same items), it did not work. I need guidance on this.
I've written the following query, so if I'm wrong on how to design the select statement or if somebody is utilising the cursor approach, please give specifics.
Query :
with final_order as (
select 121212 po,11111 item ,20 sw_need,30 order_det from dual union all
select 131313 po,22222 item ,50 sw_need,30 order_det from dual union all
select 141414 po,33333 item ,50 sw_need,40 order_det from dual union all
select 151515 po,33333 item ,50 sw_need,30 order_det from dual union all
select 161616 po,44444 item ,50 sw_need,40 order_det from dual union all
select 171717 po,44444 item ,50 sw_need,5 order_det from dual)
select item,
case
when sw_need<order_det then sw_need
when sw_need>order_det then order_det-1
else 0
end online_qty,
case
when sw_need<order_det then order_det-sw_need
when sw_need>order_det then (order_det) -(order_det-1)
else 0
end str_qty
from final_order
Query results
ITEM
ONLINE_QTY
STR_QTY
11111
20
10
22222
29
1
33333
39
1
33333
29
1
44444
39
1
44444
4
1
Expected results
PO
ITEM
SW_NEED
ORDER_DET
ONLINE_QTY
STORE_QTY
121212
11111
20
30
20
10
131313
22222
50
30
29
1
141414
33333
50
40
40
0
151515
33333
50
30
10
20
1616416
44444
50
40
40
0
171717
44444
50
5
4
1

SQL Group by range and total column

With the following function and stored procedure i get a resultset with 2 columns.
What i need additional is a third column total for all open invoices inner score range
It would great for any idea.
ALTER FUNCTION dbo.OpenOrders
(
#MandantId int
)
RETURNS TABLE
AS
RETURN
SELECT SUM(Invoices.Amount - ISNULL(Payment.Amount, 0)) AS Op
FROM Invoices INNER JOIN
Orders ON Invoices.OrderId = Orders.OrderId LEFT OUTER JOIN
Payment ON Invoices.InvoiceId = Payment.InvoiceId
WHERE (Orders.MandantId = #MandantId)
GROUP BY Invoice.InvoiceId, Invoices.Amount
HAVING (SUM(Invoices.Amount - ISNULL(Payment.Amount, 0)) <> 0)
ALTER PROCEDURE dbo.GetOpRanges
#MandantId int
AS
BEGIN
SELECT * INTO #tmp_ranges
FROM
//wrong in first post -> OPDebitorByMandant(#MandantId)
OpenOrders(#MandantId)
SELECT op AS [score range], COUNT(*) AS [number of occurences]
FROM
(SELECT CASE
WHEN op BETWEEN 0 AND 50 THEN ' 0- 50'
WHEN op BETWEEN 50 AND 100 THEN ' 50-100'
WHEN op BETWEEN 100 AND 500 THEN '100-500'
ELSE '500 and >' END AS op
FROM [#tmp_ranges]) AS t
GROUP BY op
RETURN
Result:
score range number of occurences range
------------------+-------------
0- 50 23
50-100 4
100-500 4
500 and > 21
What i need additional is a third column total for all open invoices inner score range.
Target result:
score range number of occurences Total
-----------+--------------------+------
0- 50 23 1.150
50-100 4 400
100-500 4 2.000
500 and > 21 22.000
Tables:
Invoices
InvoiceId CustomerId OrderId DateOfInvoice Amount
----------+----------+-------+-------------+------
1 1 20 20160301 1000.00
2 2 22 20160501 2000.00
3 1 102 20160601 3000.00
...
Orders
OrderId MandantId CustomerId DateOfOrder Amount
-------+---------+----------+-----------+-----------
20 1 1 20160101 1000.00
22 1 2 20160101 2000.00
102 1 1 20160101 3000.00
...
Payment
PaymentId MandantId CustomerId InvoiceId OrderId DateOfPayment Amount
---------+---------+----------+---------+-------+-------------+-------------
1 1 1 1 20 20160310 1000.00
2 1 2 2 22 20160505 2000.00
3 1 1 3 102 20160610 3000.00
...
hope it's helpfull and thanks again in advance for any solution

Treat multiple lines as one item in SQL Server

I have an invoice_detail table that stores all invoice information. Obviously the detail table stores each line item, to break out the invoice like this:
Ticket_Detail_ID Ticket_Number Customer_ID Service_Code Total
1 1 15 Book1 4.00
2 1 15 Book2 5.00
3 1 15 Book3 6.00
4 2 16 Book1 4.00
5 2 16 Book2 5.00
6 3 17 Book1 4.00
7 3 17 Book2 5.00
8 3 17 Book3 6.00
I want to Select a count of distinct tickets based on Ticket_number That does not have a "Book3" service code. So in this example I would count:
Ticket 16, since it did not have a "Book3"
It would return:
1
My query right now is:
Select Count (Distinct Ticket_Number) as Total
From Invoice_Details
Where Service_Code <> 'Book3'
This returns:
6
Use NOT EXISTS:
SELECT COUNT(DISTINCT Ticket_Number)
FROM dbo.YourTable T
WHERE NOT EXISTS(SELECT 1 FROM dbo.YourTable
WHERE Service_Code = 'Book3'
AND Ticket_Number = T.Ticket_Number)
Here is an sqlfiddle with a demo of this.

Oracle 10g unpivot returning values in one column and creating month column

We just found out that the new database we have been given access to is Oracle 10g, so we are unable to use fcn like UNPIVOT.
We have a table like this..
SUBMISSION COUNTRY CPM_ID PFM_ID T_AREA CNTRY_CODE V_TYPE RES_CAT JAN_2014 FEB_2014
01-JUN-2014 USA 10 24 TEST1 USA V1 210 5 10
01-AUG-2014 UK 20 30 TEST2 UK V1 213 20 30
The desired output would look like this...
SUBMISSION COUNTRY CPM_ID PFM_ID T_AREA CNTRY_CODE V_TYPE RES_CAT MONTH VALUE
01-JUN-2014 USA 10 24 TEST1 USA V1 210 01-JAN-2014 5
01-JUN-2014 USA 10 24 TEST1 USA V1 210 01-FEB-2014 10
01-AUG-2014 UK 20 30 TEST2 UK V1 213 01-JAN-2014 20
01-AUG-2014 UK 20 30 TEST2 UK V1 213 01-FEB-2014 30
I am working with a query like this...but I cannot get the month column to come out right...
select *
from (select t.submission,
t.country,
t.cpm_id,
t.pfm_id,
t.t_area,
t.cntry_code,
t.v_type,
t.res_cat,
(case
when n.n = 1 then JAN-2014
when n.n = 1 then FEB-2014 end) as value
from table1 t cross join
(select FEB_2014 as n from dual union all
select FEB_2014 from dual) n
) s
where value is not null;
Thanks for your help,
I would do:
select t.submission,
t.country,
t.cpm_id,
t.pfm_id,
t.t_area,
t.cntry_code,
t.v_type,
t.res_cat,
n.d,
case when n.d = '01-JAN-2014' then t.jan_2014 else t.feb_2014 end value
from table1 t
cross join
(
select '01-JAN-2014' d from dual
union all
select '01-FEB-2014' d from dual
) n;

how to write this query from 2 tables

Hear no relation have 2 table
"employee Table"
columns
Empid Empname Salary Age
1 abc 2000 20
2 xyz 3000 26
3 ijk 4000 32
4 mno 5000 50
"Groupname" table
columns
Groupid Groupname Min Max
1 young 18 25
2 middle 26 35
3 old 36 60
then i need result using both tables
empid empname age group
1 abc 2000 20 young
2 xyz 3000 26 middle
3 ijk 4000 32 middle
4 mno 5000 50 old
select empid,empname, salary, grp.groupname from employee emp left
outer join groupname grp
on ( emp.age > grp.[min] and emp.age <
grp.[max])
Try this:
select Empid, Empname, Salary, Age,Groupname
from Employee,GroupNameTable
where Age between Min and max