i have a MYSQL database where i want to sort the totals of both paind and unpaid amounts. The Query i used was :
SELECT DISTINCT
YEAR( app_payments.created_at ) AS YEARS,
SUM( app_payments.amount ) AS Total,
app_users.serial,
app_payments.`status` AS payment_state
FROM
app_payments
INNER JOIN app_users ON app_payments.created_by = app_users.serial
WHERE
app_payments.created_by = 'd88faa'
GROUP BY
YEAR ( app_payments.created_at ),
app_payments.status
i got the results as:
2017 1995 d88faa 1
2018 1200 d88faa 1
2019 1250 d88faa 0
2019 4990 d88faa 1
Where 1 stands for PAID and 0 stand for UNPAID
in my php code, i tried to group the data into years
$Stats = array ();
while(!$this->EndofSeek()){
$result = $this->Row();
if($result->payment_state == 0 ){
if(in_array($result->YEARS,$Stats)){
array_replace($Stats,['y'=>$result->YEARS , 'b'=>$result->Total ]);
}else{ array_push($Stats,['y'=>$result->YEARS , 'a'=>0 , 'b'=>$result->Total ]);}
}else if($result->payment_state == 1){
array_push($Stats,['y'=>$result->YEARS , 'a'=>$result->Total , 'b'=>0 ]);
}
}
return json_encode($Stats)
This returns the output:
[{"y":"2017","a":"1995","b":0},
{"y":"2018","a":"1200","b":0},
{"y":"2019","a":"4990","b":"1450"},
{"y":"2019","a":"4990","b":0}]
Where y is YEARS , a is PAID and b is UNPAID
What i seek to achieve is to group all the data to a particular year where i would have
[{"y":"2017","a":"1995","b":0},
{"y":"2018","a":"1200","b":0},
{"y":"2019","a":"4990","b":"1450"}]
Without it duplicating the year but rather merging them into a single unit.
What do i need to do, and which code do i need to implement to achieve this.
Do you just want conditional aggregation?
SELECT YEAR(p.created_at) AS YEAR,
SUM( CASE WHEN p.status = 0 THEN p.amount END) AS Total_0,
SUM( CASE WHEN p.status = 1 THEN p.amount END) AS Total_1
FROM app_payments p INNER JOIN
app_users u
ON p.created_by = u.serial
WHERE p.created_by = 'd88faa'
GROUP BY YEAR(p.created_at);
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last month.
The community reviewed whether to reopen this question last month and left it closed:
Original close reason(s) were not resolved
Improve this question
i am tryin to calculate profit percentage from day to day , for example :
yesterday i sold 10 items , today i sold 5 items , so the percentage must be -50% .
I've managed to make the progress but i believe i still missing something in my calculation .
My table snapshot :
when the sold items of past day is 0 the progress become infinity .
here is my javascript code :
var class_name = ( parseFloat(row.total_sold) > parseFloat( row.prev_total_sold ) ? `success` : `danger` ) ;
class_name = ( parseFloat(row.total_sold) == parseFloat( row.prev_total_sold ) ? `primary` : class_name) ;
class_name = ( row.prev_total_sold == null ? `primary` : class_name) ;
var percentage = ( ( (row.total_sold - row.prev_total_sold) / row.prev_total_sold) * 100).toFixed(1);
return `<span class="badge badge-light-${class_name} ">
<i class="fa-solid fa-arrow-trend-up text-${class_name}" style="padding-right : 5px"></i>
${percentage}%
</span>`
Row query :
prev_total_sold = is the value of sold items from past day
total_sold = is total sold items of current day
the question is : is my calculation good for the requirements ? and why i am getting infinite value when today sold is 0 !
The problem here seems to be a mathematical problem: how many times do you have to multiplicate 0 to get 5? The answer is infinity.
My suggestion here is to check if prev_total_sold is 0 then use a default value like +100%.
Modified code:
var percentage = row.prev_total_sold ? ( ( (row.total_sold - row.prev_total_sold) / row.prev_total_sold) * 100).toFixed(1) : '100.0';
You are getting infinity, because of the underlying math. Assigning a percentage for a growth from 0 to y (with y > 0) would mean there is some x such that the following equation is fulfilled
0 * x = y
And there can't be such x because 0 * something is always zero.
Displaying infinity is the next best thing that happens when you divide by zero in javascript. Other languages may throw an exception. If you want to display any other special value instead of infinity, you should check if prev_total_sold === 0 first before dividing ...
var percentage = prev_total_sold === 0
? (total_sold === 0 ? "0.0" : "some default value")
: (((row.total_sold - row.prev_total_sold) / row.prev_total_sold) * 100).toFixed(1);
In mysql there are 1 to 10 numbers available in table colum, i am fetching number and want to show alert message when number range 1 to 10 or more there are show alert "numbers are enaught". You can alert message show through javascript but embedded with php.
<?php
$sql_query = "SELECT * FROM dndorder ORDER BY display_order";
$resultset = mysqli_query($conn, $sql_query) or die("database error:". mysqli_error($conn));
$data_records = array();
while( $row = mysqli_fetch_assoc($resultset)) {
echo $row['id'];
if($row==10){
foreach (range($row, 10) as $number) {
echo 'exceed num';
}
}
}
#Simone Rossaini
this range define 0 to 9 values
this range define 0 to 9 but disorder way
Actually the numbers keep changing and the numbers keep increasing.
For example if row still showing 10 but now i want to increase some more row with others colums data may be row get reach 2 more so number will show till 0 to 11 total count 12. I want show message, when last value increase with assending order like 1 2 3 4 5 6 7 8 9 10 11 last value increase 12 just show message "Last value has been increased is 12".
The objective is to compare ColA in the Orders sheet with ColF in the Ordered Items sheet, if they match grab the email from ColB.
The script outputs no errors, but it doesn't match the highlighted cells in either sheet.
(note: the items are automatically added by an app, so the formatting of the cells are default and need to keep it that way as I'm using the last 6 digits as the order reff eg; 49.263Z)
Orders sheet
Ordered Items sheet
function getEmailFromOrderedItemToOrders(){
var orders = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Orders');
var lr = getLastRow(orders, "A1:G");
Logger.log(lr); //LastRow index
//Get last 'OrderID (Paid at)' value from 'Orders' sheet
var orderIdCol = 1;
var orderId = orders.getRange(lr, orderIdCol).getValue();
Logger.log(orderId); //LastRow 'orderId' value
//Match 'orderId' to 'orderId' in 'Ordered Items' and return col 1
var items = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Ordered Items');
var itemsData = items.getDataRange().getValues();
Logger.log(itemsData[0][1]); //'Purchase Email' col
Logger.log(itemsData[0][5]); //'Paid at' col
for(var i = 0; i<itemsData.length;i++){
if(itemsData[i][5] == orderId){ //Issue here: not comparing values as a match
var email = itemsData[i][1];
Logger.log(email); //Does not print
return i+1;
}
}
}
In javascript when you compare two new Date, you will be getting the value as false.
Reason is when you have two dates, its basically two different objects. So One object is not equal to another object when you use == or ===. So the simple and better way is converting the date to a number using .getTime() that will return how many milliseconds passed from that date and 00:00:00 of Jan 1, 1970.
Sample code snippet
console.log(new Date() === new Date())
console.log(new Date().getTime() === new Date().getTime())
This can be simply solved by using a Sheets Formula which. What you would do is:
=INDEX( 'Ordered Items!B:B', MATCH(A2, 'Ordered Items!:F:F,0) )
The formula basically says:
Return the Email Column
Find the Index (# of the row) where the value of A2 is in column Ordered Items F:F
See here for a tutorial on it: https://www.youtube.com/watch?v=9sLWDjAEuyc
I do not understand why undefined appears in result. I use a question mark (\d+)?, it matches the previous element zero or one time:
// I want to match two cases with one regexp:
// "GBP 5 per hour" and "GBP 5 per 10 hours"
//
"GBP 5 per hour".match(/([a-z]{3}) (\d+(?:\.\d+)?) per\s?(\d+)?\s?(hours?|days?|minutes?)/im)
["GBP 5 per hour", "GBP", "5", undefined, "hour"] // actual result
["GBP 5 per hour", "GBP", "5", "hour"] // the result I'd like to get
How to get rid of that undefined?
The result will be the data (text) that is matched, if you are saying you want to match zero or one, and it matches zero then there is no data to return, and undefined is the result of that.
I would speculate that the design reason as to why the match is preserved is because it keeps the indexes consistent, so you can still access them as you would expect to. This way it enables you to effective test "was anything matched" by checking for undefined.
If you want to remove it from the array then you could use the filter function, for example:
arr = arr.filter(function(e){return e});
(Which I stole from here)
try
var x = ["GBP 5 per hour", "GBP", "5", undefined, "hour"];
var y = x.filter(Boolean);
as in Javascript any non-proper value is false that should help. Found it a few months ago written by Elad here
No simpler than
"GBP 5 per hour"
.match(/([a-z]{3}) (\d+(?:\.\d+)?) per\s?(\d+)?\s?(hours?|days?|minutes?)/im)
.filter(function(i){return typeof i != 'undefined'})
Since match will return an array, you can filter its elements with the filter method. The filter method can accept a callback (closure, function name as string, ...). Array elements are iterated and every element is passed to the callback function and is only accepted if the callback return value is equivalent to Boolean True
Hope it helps
The problematic part of your RegEx is:
per\s?(\d+)?\s?
Three possible solutions:
<script type="text/javascript">
//Quick & Dirty
var $text = "GBP 5 per hour";
var $arr = $text.match(/([a-z]{3}) (\d+(?:\.\d+)?) per ?(\d+)?\s?(hours?|days?|minutes?)/im);
console.log( $arr )
var $arrTmp = []
for( var $i = 0; $i < $arr.length; $i++ )
if( typeof $arr[$i] != 'undefined' )
$arrTmp.push( $arr[$i] )
$arr = $arrTmp;
console.log( $arr );
//Different approach
var $text = "GBP 5 per hour";
var $text1 = "GBP 5 per 10 hours";
var $regEx = /([a-z]{3}) (\d+(?:\.\d+)?) per(.*)(hours?|days?|minutes?)/im
var $arr = $text.match( $regEx );
var $arr1 = $text1.match( $regEx );
if( !isNaN( parseInt( $arr[3] ) ) )
$arr[3] = parseInt( $arr[3] );
else
$arr[3] = 1;
if( !isNaN( parseInt( $arr1[3] ) ) )
$arr1[3] = parseInt( $arr1[3] );
else
$arr1[3] = 1;
console.log( $arr1 );
console.log( $arr );
</script>
undefined represents the place where the last digit you try to match should be (per\s?(\d+)) when the digit exists.
To be coherent in any case, you should keep it, and maybe handle it as if it was a 1.
If you prefer an empty string, you can try this one :
"GBP 5 per hour".match(/([a-z]{3}) (\d+(?:\.\d+)?) per\s?([\d]*)\s?(hours?|days?|minutes?)/im)
I don't know if it's possible to directly get an array without it (I mean without filtering the array).
So, I'm using this code to help sort a "Date" column in my table:
jQuery.extend( jQuery.fn.dataTableExt.oSort, {
"monthYear-pre": function ( a ) {
return new Date('01 '+a);
},
"monthYear-asc": function ( a, b ) {
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
},
"monthYear-desc": function ( a, b ) {
return ((a < b) ? 1 : ((a > b) ? -1 : 0));
}
} );
It works fine with dates such as "Jul 2012" but it won't cooperate with dates that have just the year (e.g. "2004) or have a season (e.g. Spring 2008). Also, if I've got "unknown" I'd like it to always appear last.
Any ideas? I think making the seasons analogous to a month would be the easiest way to sort that (e.g. Spring=Mar, Summer=Jun, Autumn=Sep and Winter=Dec) but I'm not sure how to go about it.
Thank you!
P.S. I'm a novice - I kind of understand what the second two strings are doing, but the first "monthYear-pre" is a mystery. If anyone would like to explain then I'd be thrilled.
"seasonYear-pre": (function() {
var seasons = /\s*(winter|spring|summer|fall|autumn),?\s*(\d{4})\s*/,
matchedMonths = {winter: '02-01', spring: '05-01',
summer: '08-01', fall: '11-01', autumn: '11-01'}
return function(a) {
var match = seasons.exec(a.toLowerCase());
return new Date(match[2] + "-" + matchedMonths[match[1]]);
};
})();
This places winter at the beginning of the year, but you can change the canonical dates in the list above as you please. It matches strings like "Winter 2012", or "Autumn, 2007". (The comma is optional, and it's case-insensitive.) I don't know this table-sorter API. I modeled this off the "monthYear-pre", but if it needs to be a plain sort method, it would be easy to change.