I have the following postgreSql table stock, there the structure is following
| column | pk |
+--------+-----+
| date | yes |
| id | yes |
| type | yes |
| qty | |
| fee | |
table looks like this
| date | id | type | qty | fee |
+------------+-----+------+------+------+
| 2015-01-01 | 001 | CB04 | 500 | 2 |
| 2015-01-01 | 002 | CB04 | 1500 | 3 |
| 2015-01-01 | 003 | CB04 | 500 | 1 |
| 2015-01-01 | 004 | CB04 | 100 | 5 |
| 2015-01-01 | 001 | CB02 | 800 | 6 |
| 2015-01-02 | 002 | CB03 | 3100 | 1 |
| | | | | |
I want to create a view or query, so that the result looks like this.
| date | type | t_qty | total_weighted_fee |
+------------+------+-------+--------------------+
| 2015-01-01 | CB04 | 2600 | 2.5 |
| 2015-01-01 | CB03 | 3100 | 1 |
| | | | |
what I did is this
http://sqlfiddle.com/#!17/39fb8a/18
But this is not the output what I want.
The Sub Query table looks like this:
% of total Qty = qty / t_qty
weighted fee = fee * % of total Qty
| date | id | type | qty | fee | t_qty | % of total Qty | weighted fee |
+------------+-----+------+------+-----+-------+----------------+--------------+
| 2015-01-01 | 001 | CB04 | 500 | 2 | 2600 | 0.19 | 0.38 |
| 2015-01-01 | 002 | CB04 | 1500 | 3 | 2600 | 0.58 | 1.73 |
| 2015-01-01 | 003 | CB04 | 500 | 1 | 2600 | 0.19 | 0.192 |
| 2015-01-01 | 004 | CB04 | 100 | 5 | 2600 | 0.04 | 0.192 |
| 2015-01-01 | 002 | CB03 | 3100 | 1 | 3100 | 1 | 1 |
| | | | | | | | |
You can use aggregation . . . I don't think you are far off:
select date, type, sum(qty),
sum(fee * qty * 1.0) / nullif(sum(qty), 0)
from t
group by date, type;
Interesting question for you all. Here's a sample of my dataset (see below). I have warehouses, dates, and the change in inventory level at that specific date for a given warehouse.
Ex: Assuming 1/1/2018 is first date, warehouse 1 starts out with 100 in inventory, then 600, then 300, then 500...etc.
My question I'd like to answer in SQL: By warehouse ID, did each warehouse ever have inventory of more than 750 (yes/no)?
I can't sum the entire column, because the ending inventory (sum of column by warehouse) is likely lower than a past inventory level. Any help is appreciated!!
+--------------+------------+---------------+
| Warehouse_id | Date | Inventory_Amt |
+--------------+------------+---------------+
| 1 | 1/1/2018 | +100 |
| 1 | 6/1/2018 | +500 |
| 1 | 6/15/2018 | -300 |
| 1 | 7/1/2018 | +200 |
| 1 | 8/1/2018 | -400 |
| 1 | 12/15/2018 | +100 |
| 2 | 1/1/2018 | +10 |
| 2 | 6/1/2018 | +50 |
| 2 | 6/15/2018 | -30 |
| 2 | 7/1/2018 | +20 |
| 2 | 8/1/2018 | -40 |
| 2 | 12/15/2018 | +10 |
| 3 | 1/1/2018 | +100 |
| 3 | 6/1/2018 | +500 |
| 4 | 6/15/2018 | +300 |
| 4 | 7/1/2018 | +200 |
| 4 | 8/1/2018 | -400 |
| 4 | 12/15/2018 | +100 |
+--------------+------------+---------------+
You want a cumulative sum and then filtering:
select i.*
from (select i.*, sum(inventory_amt) over (partition by warehouse_id order by date) as inventory
from inventory i
) i
where inventory_amt > 750
Which way we can use to check and compare the dates from one table to another.
Table : inc
+--------+---------+-----------+-----------+-------------+
| inc_id | cust_id | item_id | serv_time | inc_date |
+--------+---------+-----------+-----------+-------------+
| 1 | john | HP | 40 | 17-Apr-2015 |
| 2 | John | HP | 60 | 10-Jan-2016 |
| 3 | Nick | Cisco | 120 | 11-Jan-2016 |
| 4 | samanta | EMC | 180 | 12-Jan-2016 |
| 5 | Kerlee | Oracle | 40 | 13-Jan-2016 |
| 6 | Amir | Microsoft | 300 | 14-Jan-2016 |
| 7 | John | HP | 120 | 15-Jan-2016 |
| 8 | samanta | EMC | 20 | 16-Jan-2016 |
| 9 | Kerlee | Oracle | 10 | 2-Feb-2017 |
+--------+---------+-----------+-----------+-------------+
Table: Contract:
+-----------+---------+----------+------------+
| item_id | con_id | Start | End |
+-----------+---------+----------+------------+
| Dell | DE2015 | 1/1/2015 | 12/31/2015 |
| HP | HP2015 | 1/1/2015 | 12/31/2015 |
| Cisco | CIS2016 | 1/1/2016 | 12/31/2016 |
| EMC | EMC2016 | 1/1/2016 | 12/31/2016 |
| HP | HP2016 | 1/1/2016 | 12/31/2016 |
| Oracle | OR2016 | 1/1/2016 | 12/31/2016 |
| Microsoft | MS2016 | 1/1/2016 | 12/31/2016 |
| Microsoft | MS2017 | 1/1/2017 | 12/31/2017 |
+-----------+---------+----------+------------+
Result:
+-------+---------+---------+--------------+
| Calls | Cust_id | Con_id | Tot_Ser_Time |
+-------+---------+---------+--------------+
| 2 | John | HP2016 | 180 |
| 2 | samanta | EMC2016 | 200 |
| 1 | Nick | CIS2016 | 120 |
| 1 | Amir | MS2016 | 300 |
| 1 | Oracle | OR2016 | 40 |
+-------+---------+---------+--------------+
MY Query:
select count(inc_id) as Calls, inc.cust_id, contract.con_id,
sum(inc.serv_time) as tot_serv_time
from inc inner join contract on inc.item_id = contract.item_id
where inc.inc_date between '2016-01-01' and '2016-12-31'
group by inc.cust_id, contract.con_id
The result from inc table with filter between 1-jan-2016 to 31-Dec-2016 with
count of inc_id based on the items and its contract start and end dates .
If I understand correctly your problem, this query will return the desidered result:
select
count(*) as Calls,
inc.cust_id,
contract.con_id,
sum(inc.serv_time) as tot_serv_time
from
inc inner join contract
on inc.item_id = contract.item_id
and inc.inc_date between contract.start and contract.end
where
inc.inc_date between '2016-01-01' and '2016-12-31'
group by
inc.cust_id,
contract.con_id
the question is a little vague so you might need some adjustments to this query.
select
Calls = count(*)
, Cust = i.Cust_id
, Contract = c.con_id
, Serv_Time = sum(Serv_Time)
from inc as i
inner join contract as c
on i.item_id = c.item_id
and i.inc_date >= c.[start]
and i.inc_date <= c.[end]
where c.[start]>='20160101'
group by i.Cust_id, c.con_id
order by i.Cust_Id, c.con_id
returns:
+-------+---------+----------+-----------+
| Calls | Cust | Contract | Serv_Time |
+-------+---------+----------+-----------+
| 1 | Amir | MS2016 | 300 |
| 2 | John | HP2016 | 180 |
| 1 | Kerlee | OR2016 | 40 |
| 1 | Nick | CIS2016 | 120 |
| 2 | samanta | EMC2016 | 200 |
+-------+---------+----------+-----------+
test setup: http://rextester.com/WSYDL43321
create table inc(
inc_id int
, cust_id varchar(16)
, item_id varchar(16)
, serv_time int
, inc_date date
);
insert into inc values
(1,'john','HP', 40 ,'17-Apr-2015')
,(2,'John','HP', 60 ,'10-Jan-2016')
,(3,'Nick','Cisco', 120 ,'11-Jan-2016')
,(4,'samanta','EMC', 180 ,'12-Jan-2016')
,(5,'Kerlee','Oracle', 40 ,'13-Jan-2016')
,(6,'Amir','Microsoft', 300 ,'14-Jan-2016')
,(7,'John','HP', 120 ,'15-Jan-2016')
,(8,'samanta','EMC', 20 ,'16-Jan-2016')
,(9,'Kerlee','Oracle', 10 ,'02-Feb-2017');
create table contract (
item_id varchar(16)
, con_id varchar(16)
, [Start] date
, [End] date
);
insert into contract values
('Dell','DE2015','20150101','20151231')
,('HP','HP2015','20150101','20151231')
,('Cisco','CIS2016','20160101','20161231')
,('EMC','EMC2016','20160101','20161231')
,('HP','HP2016','20160101','20161231')
,('Oracle','OR2016','20160101','20161231')
,('Microsoft','MS2016','20160101','20161231')
,('Microsoft','MS2017','20170101','20171231');
+------------+--------+-----------+---------------+
| paydate | salary | ninumber | payrollnumber |
+------------+--------+-----------+---------------+
| 2015-05-15 | 1000 | jh330954b | 6 |
| 2015-04-15 | 1250 | jh330954b | 5 |
| 2015-03-15 | 800 | jh330954b | 4 |
| 2015-02-15 | 894 | jh330954b | 3 |
| 2015-05-15 | 500 | ew56780e | 6 |
| 2015-04-15 | 1500 | ew56780e | 5 |
| 2015-03-15 | 2500 | ew56780e | 4 |
| 2015-02-15 | 3000 | ew56780e | 3 |
| 2015-05-15 | 400 | rt321298z | 6 |
| 2015-04-15 | 582 | rt321298z | 5 |
| 2015-03-15 | 123 | rt321298z | 4 |
| 2015-02-15 | 659 | rt321298z | 3 |
+------------+--------+-----------+---------------+
The above list is the data in my database. I need to get the average of the previous 3 salaries for each individual and output this.
I don't know where to begin with this so I cannot provide any of my working so far.
In SQL Server, you can use row_number() to get the last three salaries in a subquery. Then use avg():
select ninumber, avg(salary)
from (select t.*,
row_number() over (partition by ninumber order by payrollnumber desc) as seqnum
from table t
) t
where seqnum <= 3
group by ninumber;
I'm creating inventory report mainly to show current qty, sum of qty that was reserved from customers and Total Qty that available .
As I used LEFT JOIN and RIGHT JOIN but it couldn't work, so I'm thinking of UNION function but I could't make it work. Could you please help me. Thank you very much.
tbl_inventory
inv_id | pd_id | inv_qty_act | inv_date | inv_note
1 | 001 | 120 | 20-Sep-12|
2 | 003 | 387 | 1-Oct-12 |
tbl_reserve
res_id | cust_id | res_date | res_duedate | pd_id | res_qty | if_sent | res_note
3 | 10 | 01-Oct-12| 17-Oct-12 | 001 | 135 | |
4 | 9 | 01-Oct-12| 24-Oct-12 | 001 | 253 | |
5 | 22 | 01-Oct-12| 17-Oct-12 | 001 | 132 | |
6 | 2 | 01-Oct-12| 24-Oct-12 | 002 | 446 | |
tbl_product
pd_id | pd_name
001 | des1
002 | des2
003 | des3
tbl_pdtn_startup
pdtn_st_id | pd_id | pdtn_qty_est
2 | 002 | 200
3 | 003 | 100
Output that I want :
pd_id| pd_name| inv_qty_act|pdtn_qty_est| Sum(res_qty)| Total[(inv_qty_est) - Sum(res_qty)]
001 | des1 | 120 | 0 | 520 | -400 -->(120-520)
002 | des2 | 0 | 200 | 446 | -446 -->(0-446)
003 | des3 | 387 | 100 | 0 | 387
what about this?
SELECT
tbl_product.pd_id,
tbl_product.pd_name,
( SELECT Sum(inv_qty_act) FROM tbl_inventory AS t1
WHERE t1.pd_id=tbl_product.pd_id) AS SumOfinv_qty_act,
( SELECT Sum(pdtn_qty_est) FROM tbl_pdtn_startup AS t2
WHERE t2.pd_id =tbl_product.pd_id) AS SumOfpdtn_qty_est,
( SELECT Sum(res_qty) FROM tbl_reserve AS t3
WHERE t3.pd_id=tbl_product.pd_id) AS SumOfres_qty,
IIF(ISNULL([SumOfinv_qty_act]),0,[SumOfinv_qty_act])-
IIF(ISNULL([SumOfres_qty]),0,[SumOfres_qty]) AS Total
FROM
tbl_product;