With this Query I get this result. The idea is i have a date of the product that is sold. When check if the date is between date_start and date_end of the marketing table, if so put that price in the marketingprice.
In some cases there is no end. This mean it's still running and has no end date. We still use them.
Because there is no end date I want to use the date of today. So if E (date_end) is empty , use the today date if not then use E
=query(Marketing!$B$2:E,
"select C,D where B='" & D2 & "' and
D<=date '"&TEXT(E2,"yyyy-MM-dd")&"' and
date'"&TEXT(today(),"yyyy-MM-dd")&"'>=date '"&TEXT(E2,"yyyy-MM-dd")&"' ")
+------------+---------------+--------+-----------------+----------+----------------+
| product_no | product_price | amount | deliver_country | datum | marketingprice |
+------------+---------------+--------+-----------------+----------+----------------+
| 1001 | 2.8 | 2 | de | 2-1-2020 | |
+------------+---------------+--------+-----------------+----------+----------------+
+-----+------------+
| 3.2 | 01-01-2020 |
| 1.2 | 02-01-2020 |
+-----+------------+
I want to use IF(isblank(E),date'"&TEXT(TODAY(),"yyyy-MM-dd")&"', E)
Then the code will be
=query(Marketing!$B$2:E,
"select C,D where B='" & D2 & "' and
D<=date '"&TEXT(E2,"yyyy-MM-dd")&"' and
IF(isblank(E),date'"&TEXT(today(),"yyyy-MM-dd")&"',E)>=date '"&TEXT(E2,"yyyy-MM-dd")&"' ")
Then I get a error:
QUERY: PARSE_ERROR: Encountered " "IF "" at line 1, column 58.
Was expecting one of: "(" ... "(" ...
Marketing Table
+---------+---------+-------+-------------+------------+
| channel | country | price | date_start | date_end |
+---------+---------+-------+-------------+------------+
| Google | de | 3.2 | 01-01-2020 | 01-01-2020 |
| Google | de | 1.2 | 02-01-2020 | |
| Amazon | en | 5.4 | 01-01-2020 | |
+---------+---------+-------+-------------+------------+
Output how it should be
+------------+---------------+--------+-----------------+----------+----------------+
| product_no | product_price | amount | deliver_country | datum | marketingprice |
+------------+---------------+--------+-----------------+----------+----------------+
| 1001 | 2.8 | 2 | de | 2-1-2020 | 1.2 |
| 1002 | 3.8 | 4 | en | 3-1-2020 | 5.4 |
| 1001 | 2.8 | 1 | de | 1-1-2020 | 3.2 |
+------------+---------------+--------+-----------------+----------+----------------+
In mysql I use this code :
b.start_date <= date(i.system_created) AND
coalesce(b.end_date,now()) >= date(i.system_created)
Solution i found myself:
=QUERY(Marketing!$B$2:$E;IF(Marketing!E$2:E="";
"select E where B ='"&D2&"' and D <=date'"&TEXT(E2;"yyyy-MM-dd")&"' and date'"&TEXT(VANDAAG();"yyyy-MM-dd")&"' >=date'"&TEXT(E2;"yyyy-MM-dd")&"' limit 1";
"select E where B ='"&D2&"' and D <=date'"&TEXT(E2;"yyyy-MM-dd")&"' and E >=date'"&TEXT(E2;"yyyy-MM-dd")&"'"
);0)
try:
=ARRAYFORMULA(IFERROR(QUERY(
{Marketing!B$2:D\ IF(Marketing!E$2:E=""; TODAY(); Marketing!E$2:E)};
"select Col2
where Col1 = '"&D2&"'
and Col3 <= date '"&TEXT(E2;"yyyy-MM-dd")&"'
and Col4 <= "&TODAY()&"
limit 1"; 0)))
You could use Apps Script to solve this issue.
How does it work?
Assign Sales data (D2:E7) to sales variable, Marketing data (B2:E7) to marketing variable.
in for loop through sales and if sale_date < date_start set cell value as marketing_cost - 1
Below you can find a screenshot attached before and after.
function worker(){
let ss = SpreadsheetApp.getActive();
let sheetSales = ss.getSheetByName("Sales");
let sheetMarketing = ss.getSheetByName("Marketing");
// 1.
let sales = sheetSales.getRange("D2:E7").getValues();
/** sales
[
[de, 02-01-2020],
[de, 03-01-2020],
[de, 04-01-2020],
[de, 06-01-2020],
[de, 10-01-2020],
[en, 10-01-2020]
]
*/
let marketing = sheetMarketing.getRange("B2:E7").getValues();
/** marketing
[
[de, 3.2, 01-01-2020, 02-01-2020],
[de, 1.2, 03-01-2020, 04-01-2020],
[de, 4.4, 05-01-2020, 06-01-2020],
[de, 8.8, 07-01-2020, 08-01-2020],
[de, 9.9, 09-01-2020, 25-02-2020],
[en, 5.4, 01-01-2020, 25-02-2020]
]
*/
let sale_date,
date_start,
date_end,
marketing_cost = [];
for(let i = 0; i < sales.length; i++){
sale_date = new Date(sales[i][1]);
date_start = new Date(marketing[i][2]);
date_end = new Date(marketing[i][3]);
marketing_cost.push(marketing[i][1]);
// 2.
if(sale_date < date_start){
sheetSales.getRange(2+i, 6).setValue(marketing_cost[i-1]);
}else{
sheetSales.getRange(2+i, 6).setValue(marketing_cost[i]);
}
}
}
Before:
After:
Reference:
Spreadsheet Service
Column GrossCommission displays value 368.760000 but I need it to be 368.75.
Column NetDueCarrier displays value 31.240000 but I need it to be 31.25
Below is the calculation for those values:
SELECT
policyNumber,
CompanyCommission,
CASE WHEN [GrossPremium] < 0 THEN [BondAmount] * (-1) ELSE [BondAmount] END as [NetPenalLiability],
GrossPremium as WrittenPremium,
PayableFees,
(GrossPremium * (CompanyCommissionActual /100)) as GrossCommission,
BillDate,
PolicyType,
((GrossPremium - (GrossPremium * (CompanyCommissionActual / 100))) + PayableFees) as NetDueCarrier
If you need the value to the nearest 5 cent, then you could use something like this:
create table t (val decimal(9,4));
insert into t values
(31.20),(31.21),(31.22),(31.23),(31.24)
,(31.25),(31.26),(31.27),(31.28),(31.29);
select
val
, Nearest5 = round(val/.05,0)*.05
-- , Nearest5 = round(val*20,0)/20 -- alternate way of writing the expression
from t
rextester demo: http://rextester.com/UUNA22566
returns:
+---------+----------+
| val | Nearest5 |
+-------+----------+
| 31.20 | 31.20 |
| 31.21 | 31.20 |
| 31.22 | 31.20 |
| 31.23 | 31.25 |
| 31.24 | 31.25 |
| 31.25 | 31.25 |
| 31.26 | 31.25 |
| 31.27 | 31.25 |
| 31.28 | 31.30 |
| 31.29 | 31.30 |
+-------+----------+
You could simply wrap the calculation in a ROUND function:
ROUND(GrossPremium * (CompanyCommissionActual /100), 2) as GrossCommission,
...
ROUND((GrossPremium - (GrossPremium * (CompanyCommissionActual / 100))) + PayableFees, 2) as NetDueCarrier
More info here. This is assuming you're using SQL Server with a version >= 2008.
Thanks for all the help that you all provided and though it was an eye opener unfortunately it did not produce the expected results I was looking for. In an effort to better get the help I'm looking for I will try to explain what I'm looking to achieve.
I think the main columns of focus are "IN", "AA_Now", "STF_Now", "dbo.Sheet1$.LOB_name", "dbo.Sheet1$.LifeCycleName" and "dbo.Sheet1$.AreaOfBusiness". Each "IN" have an "AA_Now" and "STF_Now". A group of "IN" rolls up under "dbo.Sheet1$.LOB_name". Under "dbo.Sheet1$.LOB_name" I just want the max value of the Group of "IN" that is rolled up. Now "dbo.Sheet1$.LOB_name" is rolled up under "dbo.Sheet1$.LifeCycleName" and what I want is the sum of of the max values that are rolled up under "dbo.Sheet1$.LOB_name" to show in the rollup of "dbo.Sheet1$.LifeCycleName". Finally "dbo.Sheet1$.LifeCycleName" rolls up to "dbo.Sheet1$.AreaOfBusiness". As before what I'm looking for is the sum of "dbo.Sheet1$.LifeCycleName" to show. These are only for the columns of "AA_Now" and "STF_Now"
I tried doing it from a Pivot table but to no avail and figured that it would be best to sort it out in the raw data.
I'm trying to to do a SUM(MAX) calculation in SQL server and getting the follow error when executing the command
Msg 130, Level 15, State 1, Line 6
Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
I'm sure the error is caused by both
,SUM(MAX(convert(float,replace([AA_Now], 'N/A','0')))) As [AA2_Now]
and
,SUM(MAX(convert(float,replace([STF_Now], 'N/A','0')))) As [STF2_Now]
but have no idea how to rewrite it without causing an error.
Below is the full code.
SELECT dbo.CCA_Merged.id, dbo.CCA_Merged.timeStamp, dbo.CCA_Merged.name, dbo.CCA_Merged.lN
,dbo.CCA_Merged.type, dbo.CCA_Merged.id2, dbo.CCA_Merged.aG
,dbo.CCA_Merged.regionId, dbo.CCA_Merged.sgcc
,convert(float,replace([SLC_Today],'N/A','0')) As [SLC_Today]
,convert(float,replace([AA_Now],'N/A','0')) As [AA_Now]
,SUM(MAX(convert(float,replace([AA_Now],'N/A','0')))) As [AA2_Now]
,convert(float,replace([SLCO_Today],'N/A','0')) As [SLCO_Today]
,convert(float,replace([CABN_Today],'N/A','0')) As [CABN_Today]
,convert(float,replace([COF_Today],'N/A','0')) As [COF_Today]
,convert(float,replace([HT_Today],'N/A','0')) As [HT_Today]
,convert(float,replace(replace([CH_Today],'N/A','0'),'-','0')) As [CH_Today]
,convert(float,replace([SLC_Now],'N/A','0')) As [SLC_Now]
,convert(float,replace([SLCO_Now],'N/A','0')) As [SLCO_Now]
,convert(float,replace([SLC_Thirty],'N/A','0')) As [SLC_Thirty]
,convert(float,replace(replace([SLCO_Thirty],'N/A','0'),'-','0')) As [SLCO_Thirty]
,convert(float,replace([ACWT_Today],'N/A','0')) As [ACWT_Today]
,convert(float,replace([CQ_Now],'N/A','0')) As [CQ_Now]
,convert(float,replace([LCQ_Now],'N/A','0')) As [LCQ_Now]
,convert(float,replace([SLCH_Now],'N/A','0')) As [SLCH_Now]
,convert(float,replace([STF_Now],'N/A','0')) As [STF_Now]
,SUM(MAX(convert(float,replace([STF_Now],'N/A','0')))) As [STF2_Now]
,dbo.Sheet1$.AreaOfBusiness, dbo.Sheet1$.LifeCycleName, dbo.Sheet1$.LOB_name
FROM dbo.Sheet1$ RIGHT OUTER JOIN
dbo.CCA_Merged ON dbo.Sheet1$.Skill_Name = dbo.CCA_Merged.lN
Group by ROLLUP (stf_now) ,dbo.CCA_Merged.id, dbo.CCA_Merged.timeStamp, dbo.CCA_Merged.name, dbo.CCA_Merged.lN
,dbo.CCA_Merged.type, dbo.CCA_Merged.id2, dbo.CCA_Merged.aG ,dbo.CCA_Merged.regionId
,dbo.CCA_Merged.sgcc,AA_Now,SLC_Today,SLCO_Today,CABN_Today,COF_Today,HT_Today,CH_Today
,SLC_Now,SLCO_Now,SLC_Thirty,SLCO_Thirty,ACWT_Today,CQ_Now,LCQ_Now,SLCH_Now
,dbo.Sheet1$.AreaOfBusiness, dbo.Sheet1$.LifeCycleName, dbo.Sheet1$.LOB_name
I'm relatively new with SQL Server and any help would be greatly appreciated.
Thanks in advance
Updated Stripped down script
SELECT dbo.CCA_Merged.lN
,convert(float,replace([STF_Now],'N/A','0')) As [STF_Now]
,dbo.Sheet1$.LOB_name, dbo.Sheet1$.LifeCycleName, dbo.Sheet1$.AreaOfBusiness
FROM dbo.Sheet1$ RIGHT OUTER JOIN
dbo.CCA_Merged ON dbo.Sheet1$.Skill_Name = dbo.CCA_Merged.lN
Group by stf_now ,AA_Now,dbo.CCA_Merged.lN,dbo.Sheet1$.AreaOfBusiness, dbo.Sheet1$.LifeCycleName, dbo.Sheet1$.LOB_name
Order by AreaOfBusiness DESC
+----+---------+----------+---------------+----------------+
| LN | STF_Now | LOB_name | LifeCycleName | AreaOfBusiness |
+----+---------+----------+---------------+----------------+
| A | 46 | BSW | BS | Business |
| B | 46 | BSW | BS | Business |
| C | 0 | BOSS | BS | Business |
| D | 112 | MSD | BS | Business |
| E | 112 | MSD | BS | Business |
| F | 42 | BHV | BR | Business |
| G | 23 | BCR | BR | Business |
| H | 23 | BHV | BR | Business |
| I | 55 | BSW2 | BS | Business |
| J | 1 | BSW2 | BS | Business |
| K | 46 | BSW | BS | Business |
| L | 112 | MSD | BS | Business |
| M | 112 | MSD | BS | Business |
| N | 57 | BSW | BS | Business |
| O | 0 | BOSS | BS | Business |
| P | 38 | MSD | BS | Business |
| Q | 38 | MSD | BS | Business |
| R | 19 | BHV | BR | Business |
| S | 0 | BCR | BR | Business |
| T | 19 | BHV | BR | Business |
| U | 2 | BSW | BS | Business |
| V | 1 | BSW | BS | Business |
| W | 57 | BSW | BS | Business |
| X | 38 | MSD | BS | Business |
| Y | 38 | MSD | BS | Business |
+----+---------+----------+---------------+----------------+
Below is the the expected results in 3 added columns
LOB_Name2 (This is the Max of STF_Now resulting from LN)
57 BSW
0 BOSS
112 MSD
42 BHV
23 BCR
55 BSW2
LifeCycleName2 (This is the Sum of the Max of the Rollup of LOB_Name2)
224 BS
65 BR
AreaOfBusiness2 (This is the Sum of the Rollup of LifeCycleName2)
289 Business
You can't sum a max because it would be the same amount anyhow, if you have the same group by. You probably need to have an inner and outer parts with different group by, something like:
select
product_group,
sum(max_cost)
from
(
select
product,
product_group,
max(cost) as max_cost
from
orders
group by
product_group,product
) X
group by product_group
This imaginary SQL will fetch maximum cost for each product, and them sum them up to the product group level. That's the only way I can figure out you'd actually need to sum a max
You're having issues because you're trying to do two nested aggregates. This will roughly give you what you're after, if SUM(MAX) is actually what you're trying to do.
However, as James pointed out, You'll need some group by logic that pulls this together.
SELECT ...
, SUM(AA2_Now_Max)
...
, SUM(STF2_Now_Max)
FROM(
SELECT dbo.CCA_Merged.id, dbo.CCA_Merged.timeStamp, dbo.CCA_Merged.name, dbo.CCA_Merged.lN
,dbo.CCA_Merged.type, dbo.CCA_Merged.id2, dbo.CCA_Merged.aG
,dbo.CCA_Merged.regionId, dbo.CCA_Merged.sgcc
,convert(float,replace([SLC_Today],'N/A','0')) As [SLC_Today]
,convert(float,replace([AA_Now],'N/A','0')) As [AA_Now]
,MAX(convert(float,replace([AA_Now],'N/A','0'))) As [AA2_Now_Max]
,convert(float,replace([SLCO_Today],'N/A','0')) As [SLCO_Today]
,convert(float,replace([CABN_Today],'N/A','0')) As [CABN_Today]
,convert(float,replace([COF_Today],'N/A','0')) As [COF_Today]
,convert(float,replace([HT_Today],'N/A','0')) As [HT_Today]
,convert(float,replace(replace([CH_Today],'N/A','0'),'-','0')) As [CH_Today]
,convert(float,replace([SLC_Now],'N/A','0')) As [SLC_Now]
,convert(float,replace([SLCO_Now],'N/A','0')) As [SLCO_Now]
,convert(float,replace([SLC_Thirty],'N/A','0')) As [SLC_Thirty]
,convert(float,replace(replace([SLCO_Thirty],'N/A','0'),'-','0')) As [SLCO_Thirty]
,convert(float,replace([ACWT_Today],'N/A','0')) As [ACWT_Today]
,convert(float,replace([CQ_Now],'N/A','0')) As [CQ_Now]
,convert(float,replace([LCQ_Now],'N/A','0')) As [LCQ_Now]
,convert(float,replace([SLCH_Now],'N/A','0')) As [SLCH_Now]
,convert(float,replace([STF_Now],'N/A','0')) As [STF_Now]
,MAX(convert(float,replace([STF_Now],'N/A','0'))) As [STF2_Now_Max]
,dbo.Sheet1$.AreaOfBusiness, dbo.Sheet1$.LifeCycleName, dbo.Sheet1$.LOB_name
FROM dbo.Sheet1$ RIGHT OUTER JOIN
dbo.CCA_Merged ON dbo.Sheet1$.Skill_Name = dbo.CCA_Merged.lN
Group by ROLLUP (stf_now) ,dbo.CCA_Merged.id, dbo.CCA_Merged.timeStamp, dbo.CCA_Merged.name, dbo.CCA_Merged.lN
,dbo.CCA_Merged.type, dbo.CCA_Merged.id2, dbo.CCA_Merged.aG ,dbo.CCA_Merged.regionId
,dbo.CCA_Merged.sgcc,AA_Now,SLC_Today,SLCO_Today,CABN_Today,COF_Today,HT_Today,CH_Today
,SLC_Now,SLCO_Now,SLC_Thirty,SLCO_Thirty,ACWT_Today,CQ_Now,LCQ_Now,SLCH_Now
,dbo.Sheet1$.AreaOfBusiness, dbo.Sheet1$.LifeCycleName, dbo.Sheet1$.LOB_name ) x
GROUP BY ...
This other question is similar- follow the pattern! SQL: SUM the MAX values of results returned
You need to add another query level to SUM your MAX values.
The idea would be to MAX in one select and then SUM the results using a outer query. I use AVG and MAX in the example below, however, any aggregate function could be used.
SELECT
LocationID,
MaxAverageSalePriceByLocation=MAX(AvgerageSalePriceByUserLocation)
FROM
(
SELECT
UserID,
AvgerageSalePriceByUserLocation=AVG(SalePrice)
FROM
MyTable
GROUP BY
UserID,LocationID
)AS A
GROUP BY
LocationID
If you want to sum all the rows Max values then use OVER()
Sum(Max(CONVERT(FLOAT, Replace([STF_Now], 'N/A', '0'))))OVER() AS [STF2_Now]
If you want to sum all the rows Max values for each group then use OVER(Partition by)
Sum(Max(CONVERT(FLOAT, Replace([STF_Now], 'N/A', '0'))))OVER(partition by grp1,grp2,..) AS [STF2_Now]
Note Converting the numeric data to float could lead to approximation issues.. Use Numeric with precision and scale
I want to union ranges from any Google spreadsheets.
The example
Sheet1!A:A
{12, 131, 45}
Sheet2!A:A
{12, 131, 46}
The unknown function
=formula_for_union_range(Sheet1!A:A; Sheet2!:A:A)
should return
{12, 131, 45, 12, 131, 46}
The question
How is it possible?
Just use:
={sheet1!a:a; sheet2!a:a}
You can merge them into 1 column then get the unique values. Check the following formula:
=UNIQUE({Sheet1!A:A;Sheet2!A:A})
Google Apps Script
And yet the question was about the script. I'm still successfully using the following code:
function unionRanges(e) {
var result = [];
var length = 0;
var i = 0;
try {
for (i = 0; i < arguments.length; i++)
length += arguments[i].length;
if (length > 3000) return '#BIGRANGE';
for (var i = 0; i < arguments.length; i++)
result = result.concat(arguments[i].filter(function (el) {
return el.join('').length > 0
}));
return result;
} catch (err) {
return JSON.stringify(err);
}
}
Spreadsheets feature
But, as noted above, it is easier to use {}-notation.
={ Sheet1!A1:C10 ; Sheet2!A1:C34 }
Vertical concatenation
={ Range(Cols=N) ; Range(Cols=N) }
Horizontal concatenation
={ Range(Rows=M) , Range(Rows=M) }
It's possible to combine
={ { , , } ; { , , } }
Or something more hard
={{{;;},{;;}};{{;;},{;;}};{{;;},{;;}}}
Try something like this
={
{{ 1; 2; 3},{ 4; 5; 6}};
{{ 7; 8; 9},{10;11;12}};
{{13;14;15},{16;17;18}}
}
The internal horizontal concatenation is not required
={
{ 1; 2; 3},{ 4; 5; 6};
{ 7; 8; 9},{10;11;12};
{13;14;15},{16;17;18}
}
Locale dependencies of argument delimiters
If your current locale supports , as an argument delimiter thnen you should use ; for a vertical concatenation and , for a horizontal concatenation.
Otherwise your argument delimiter is ; and you have to use ; and \ (without spaces), respectively.
Sheet 'Data 1'!A1:C20
| Name | Date | Sum |
| Ethan | 3/4/2017 | 31 |
| Logan | 3/6/2017 | 62 |
| Brian | 3/26/2017 | 61 |
| ... | ... | ... |
Sheet 'Data 2'!A1:C20
| Name | Date | Sum |
| Nathan | 3/30/2017 | 53 |
| Alyssa | 3/13/2017 | 72 |
| John | 3/24/2017 | 79 |
| Megan | 3/16/2017 | 10 |
| ... | ... | ... |
Concatenation
Vertical concatenation
={'Data 1'!A1:C20;'Data 2'!A2:C20}
Result
| Name | Date | Sum |
| Ethan | 3/4/2017 | 31 |
| Logan | 3/6/2017 | 62 |
| Brian | 3/26/2017 | 61 |
| ... | ... | ... |
| Nathan | 3/30/2017 | 53 |
| Alyssa | 3/13/2017 | 72 |
| John | 3/24/2017 | 79 |
| ... | ... | ... |
Horizontal concatenation
={TRANSPOSE('Data 1'!A1:C20),TRANSPOSE('Data 2'!A2:C20)}
Result
| Name | Ethan | Logan | Brian | ... | Nathan | Alyssa | John |
| Date | 3/4/2017 | 3/6/2017 | 3/26/2017 | ... | 3/30/2017 | 3/13/2017 | 3/24/2017 |
| Sum | 31 | 62 | 61 | ... | 53 | 72 | 79 |
More about this How to concatenate ranges in Google spreadsheets
Although a script can do this easily, I recommend using regular spreadsheet formulas, e.g.
=transpose(split(join(";";Sheet1!A:A)&";"&join(";";Sheet2!A:A);";"))
To remove duplicates, just wrap it in a unique formula:
=unique(transpose(...))
And to sort... =sort(...)
At first when I tried ={Sheet1!A:A; Sheet2!A:A}, I thought it didn't work because I could only see results from the first sheet. Turned out it was including all the blank cells too!
To filter out blank and empty cells while preserving duplicates (unlike =UNIQUE) and without repeating yourself (unlike =FILTER()), you can use =QUERY(), like so:
=QUERY(
{March!A1:Z; April!A2:Z; May!A2:Z},
"select * where Col1 != '' and Col1 is not null",
0)
(Note that I am including the header row from the first sheet, and omitting it from the other sheets).
If your sheets don't contain cells with empty text, you can omit Col1 != '' and.
Suppose you have:
A B C D E F
1: 1 2 3 4 5 6
It's possible to concatenate slices as either rows or columns.
For additional columns (same row), use a comma. ={$A1:$C1,$D1:$F1} yields:
1 2 3 4 5 6
For additional rows (same columns), use a semicolon. ={$A1:$C1;$D1:$F1} yields:
1 2 3
4 5 6
If you want to union sheets and exclude rows with empty cells use the FILTER function in your formula:
=FILTER({Sheet1!A:A;Sheet2!A:A}, {Sheet1!A:A;Sheet2!A:A}<>"")