I have 2 tables :
payments:
id amount type code
1 1200 0 111
2 100 1 111
3 200 0 111
4 50 0 112
5 500 2 112
6 300 3 113
bills:
id details code
-----------------------
1 bill-1 111
2 bill-2 112
3 bill-3 113
4 bill-4 114
I wanted to sum the amounts in payments table and join it with bills like below
result:
bills.code type0Sum type1Sum type2Sum type3Sum
-------------------------------------------------------------------------
111 1400 100 0 0
112 50 0 500 0
113 0 0 0 300
114 0 0 0 0
Sorry if this is a newbie question
[Edit]
I have used a similar query as below :
SELECT *
FROM bills,
(SELECT SUM(amount) AS type0Sum, code
FROM payments
WHERE type = 0
GROUP BY code)
AS sub1,
(SELECT SUM(amount) AS type1Sum, code
FROM payments
WHERE type = 1
GROUP BY ref_code)
AS sub2
WHERE bills.code = sub1.code
AND bills.code = sub2.code
But I am getting only the rows those having the type like :
bills.code type0Sum type1Sum type2Sum type3Sum
-------------------------------------------------------
111 1400 100
I've modified that final query to do proper joins, not the old joins that you were doing (read up on cartesian joins). Give this one a go for you, see if it works;
SELECT b.code
,sub1.type0Sum
,sub2.type1Sum
FROM bills b
LEFT JOIN (
SELECT SUM(amount) AS type0Sum
,code
FROM payments
WHERE type = 0
GROUP BY code
) AS sub1 ON b.code = sub1.code
LEFT JOIN (
SELECT SUM(amount) AS type1Sum
,code
FROM payments
WHERE type = 1
GROUP BY ref_code
) AS sub2 ON b.code = sub2.code
There are other ways of doing this that are more efficient but I've kept to your query in order to help you learn.
Related
I have a table with values
KId sales_month quantity_sold
100 1 0
100 2 0
100 3 0
496 2 6
511 2 10
846 1 4
846 2 6
846 3 1
338 1 6
338 2 0
now i require output as
KId sales_month quantity_sold result
100 1 0 1
100 2 0 1
100 3 0 1
496 2 6 1
511 2 10 1
846 1 4 1
846 2 6 1
846 3 1 0
338 1 6 1
338 2 0 1
Here, the calculation has to go as such if quantity sold for the month of march(3) is less than 60% of two months January(1) and February(2) quantity sold then the result should be 1 or else it should display 0. Require solution to perform this.
Thanks in advance.
If I understand well, your requirement is to compare sold quantity in month t with the sum of quantity sold in months t-1 and t-2. If so, I can suggest using dplyr package that offer the nice feature of grouping rows and mutating columns in your data frame.
resultData <- group_by(data, KId) %>%
arrange(sales_month) %>%
mutate(monthMinus1Qty = lag(quantity_sold,1), monthMinus2Qty = lag(quantity_sold, 2)) %>%
group_by(KId, sales_month) %>%
mutate(previous2MonthsQty = sum(monthMinus1Qty, monthMinus2Qty, na.rm = TRUE)) %>%
mutate(result = ifelse(quantity_sold/previous2MonthsQty >= 0.6,0,1)) %>%
select(KId,sales_month, quantity_sold, result)
The result is as below:
Adding
select(KId,sales_month, quantity_sold, result)
at the end let us display only columns we care about (and not all these intermediate steps).
I believe this should satisfy your requirement. NA is the result column are due to 0/0 division or no data at all for the previous months.
Should you need to expand your calculation beyond one calendar year, you can add year column and adjust group_by() arguments appropriately.
For more information on dplyr package, follow this link
I am new to R and have a particular fantasy sports team optimization problem I would like to solve. I have seen other posts use lpSolve for similar problems but I can not seem to wrap my head around the code. Example data table below. Every player is on a team, plays a particular role, has a salary, and has avg points produced per game. The constraints that I need are I need exactly 8 players. No more than 3 players may come from any one team. There must be at least one player for each role (of 5). And cumulative salary must not exceed $10,000.
Team Player Role Avgpts Salary
Bears A T 22 930
Bears B M 19 900
Bears C B 30 1300
Bears D J 25 970
Bears E S 20 910
Jets F T 21 920
Jets G M 26 980
[...]
In R, I write in the following
> obj = DF$AVGPTS
> con = rbind(t(model.matrix(~ Role + 0, DF)), rep(1,nrow(DF)), DF$Salary)
> dir = c(">=",">=",">=",">=",">=","==","<=")
> rhs = c(1,1,1,1,1,8,10000)
> result = lp("max", obj, con, dir, rhs, all.bin = TRUE)
This code works fine in producing the optimal fantasy team without the limitation of no more than 3 players may come from any one team. This is where I am stuck and I suspect it relates to the con argument. Any help is appreciated.
What if you added something similar to the way you did the roles to con?
If you add t(model.matrix(~ Team + 0, DF)) you'll have indicators for each team in your constraint. For the example you gave:
> con <- rbind(t(model.matrix(~ Role + 0,DF)), t(model.matrix(~ Team + 0, DF)), rep(1,nrow(DF)), DF$Salary)
> con
1 2 3 4 5 6 7
RoleB 0 0 1 0 0 0 0
RoleJ 0 0 0 1 0 0 0
RoleM 0 1 0 0 0 0 1
RoleS 0 0 0 0 1 0 0
RoleT 1 0 0 0 0 1 0
TeamBears 1 1 1 1 1 0 0
TeamJets 0 0 0 0 0 1 1
1 1 1 1 1 1 1
930 900 1300 970 910 920 980
We now need to update dir and rhs to account for this:
dir <- c(">=",">=",">=",">=",">=",rep('<=',n_teams),"<=","<=")
rhs <- c(1,1,1,1,1,rep(3,n_teams),8,10000)
With n_teams set appropriately.
My simple database contains nodes of 'terms' and 'codes' linked to each other.
There are two types of relationships.
Relationships between 'terms' and 'codes' called :CODE and are undirected (or read in both directions equally).
Relationships between 'terms' called :NT (which means narrow term) and are directed.
I want to walk thru all the 'terms' from top to bottom and collect all the unique codes and count them.
This is my query:
MATCH (a)-[:NT*]->(b), (a)-[:CODE]-(c), (b)-[:CODE]-(d)
WHERE a.btqty = 0
RETURN a.termid AS termid, a.maxlen AS maxlen, COUNT(DISTINCT c.code) + COUNT(DISTINCT d.code) AS total, COLLECT(DISTINCT c.code) + COLLECT(DISTINCT d.code) AS codes
ORDER BY termid;
This is what I get:
termid maxlen total codes
22 2 3 ["S70","S43","S70"]
25 4 9 ["S20","S21","S54","S61","S63","S63","S21","S61","S54"]
26 2 9 ["S99","S98","S29","S13","S13","S20","S29","S14","S15"]
68 5 13 ["S38","S11","S12","S11","S12","S38","S37","S21","S36","S22","S98","S63","S58"]
123 2 3 ["S38","S12","S12"]
154 2 2 ["S58","S58"]
155 4 3 ["S63","S62","S63"]
159 2 2 ["S36","S36"]
...
I need to get rid of duplicates in collection and count them properly like this:
termid maxlen total codes
22 2 2 ["S43","S70"]
25 4 5 ["S20","S21","S54","S61","S63"]
26 2 7 ["S99","S98","S29","S13","S20","S14","S15"]
68 5 10 ["S38","S11","S12","S37","S21","S36","S22","S98","S63","S58"]
123 2 2 ["S38","S12"]
154 2 1 ["S58"]
155 4 2 ["S63","S62"]
159 2 1 ["S36"]
...
I think this is something about REDUCE function to apply but I do not know how to use it.
Thank you for your help!
You're right, this can be solved using REDUCE. Inside the reduce you need to check if the current element already exists in the accumulator and conditionally amend it:
MATCH (a)-[:NT*]->(b), (a)-[:CODE]-(c), (b)-[:CODE]-(d)
WHERE a.btqty = 0
WITH a.termid AS termid, a.maxlen AS maxlen,
REDUCE(uniqueCodes=[],
x in COLLECT(DISTINCT c.code) + COLLECT(DISTINCT d.code) |
CASE WHEN x IN uniqueCodes THEN uniqueCodes ELSE uniqueCodes+x END
) AS codes
ORDER BY termid
RETURN termid, maxlen, count(codes) as total, codes
I have some records.
ID Salary WillGroupBy Amount
----------------------------------------
6320 100 1 15
6320 150 1 20
6694 200 0 25
6694 300 0 30
7620 400 1 45
7620 500 1 50
How can I group by only which "WillGroupBy = 1" records?
(I will SUM Salary and Amount columns)
I want to get this result:
ID Salary WillGroupBy Amount
----------------------------------------
6320 250 1 35
6694 200 0 25
6694 300 0 30
7620 900 1 95
Can you help me please :( ?
Solution:
SELECT ID, SUM(Salary) Salary, WillGroupBy, SUM(Amount) Amount
FROM YourTable
where WILLGROUPBY = 0
union all
SELECT ID, SUM(Salary) Salary, WillGroupBy, SUM(Amount) Amount
FROM YourTable
where WILLGROUPBY = 1
group by ID, WillGroupBy
I used this solution via Erhan.
I would to know that how it could be in another way.
With MySQL you can do:
SELECT ID, SUM(Salary) Salary, WillGroupBy, SUM(Amount) Amount, #row := #row + 1
FROM YourTable
JOIN (SELECT #row := 0) v
GROUP BY ID, IF(WillGroupBy = 1, -1, #row)
DEMO
I have an example table:
ID | ArticleID | Price | SupplierID | dateAdded
1 1 100 1 2014-08-01
2 1 110 2 2014-08-01
3 2 105 1 2014-08-01
4 2 106 1 2014-08-01
5 2 101 2 2014-08-01
6 3 100 1 2014-08-01
7 1 107 2 2014-09-01
8 3 343 2 2014-09-01
9 3 232 2 2014-09-01
10 1 45 1 2014-09-01
I want to use .query on this table and select LAST value entered for each DISTINCT ArticleID for each SupplierID, resulting in:
ID | ArticleID | Price | SupplierID
10 1 45 1
9 3 232 2
6 3 100 1
7 1 107 2
4 2 106 1
5 2 101 2
I want to get price for last ArticleID entered for each SupplierID.
What should I enter into
public Cursor query (boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
I came up with this so far:
String[] columns = new String[]{DatabaseOpenHelper.KEY_ID, DatabaseOpenHelper.KEY_CENA, DatabaseOpenHelper.KEY_IZDELEK_ID};
Cursor crs = database.query(true,"prices", columns, selection, selectionArgs, null, null, null, null);
but now I'm stuck:S
Any hint how to do this?
You can also suggest raw query if possible..
Raw query would be like this:
SELECT ID, ArticleID, Price, SupplierID FROM your_table WHERE ID IN (SELECT max(ID) from your_table GROUP BY ArticleID, SupplierID);
I assumed the IDs are autoincremented and the more recent entries have higher ids. If that's not the case change the HAVING clause to operate on DATE column.
After fidling around a bit and help of a friend I have came with SQL query that does what I want, not sure about optimization:
select tab.* from cene tab inner join (
select izdelek_id, trgovina_id, Max(enter_date) as maxDate
from cene group by izdelek_id, trgovina_id) art
on (art.izdelek_id = tab.izdelek_id) and (art.trgovina_id = tab.trgovina_id) and (art.maxDate = tab.enter_date)
izdelek_id = ArticleID
trgovina_id = SupplierID
cene is the name of a table.
Hope it helps to somebody..