Calculating Average after MySQL Query is Run - mysql

I've run a MySQL query (this is in wordpress php):
$myQuery = $wpdb->get_results('SELECT Opponent, ROUND(AVG(Points),2)
AS Avg_Points, ROUND(AVG(Plus_Minus),2) AS Avg_Plus_Minus
FROM ' . 'afl_defense_v_position' . ' WHERE Position = "MID"
AND Rank <= 1 AND Round >= 10 GROUP BY Opponent
ORDER BY Avg_Plus_Minus DESC')
This all works fine and I can build an html table off this no problem.
What I am looking to do now though is find the standard deviation and average of the resulting Avg_Plus_Minus column and assign them to php variables so that I can use them to colour the table rows.
How do I assign these variables? (Once assigned I know how to code the colours)
I know how to do this by running another MySQL query and modifying the aforementioned code, however, I assume there is an easier way to calculate these from the array result of the original query.
Any help is appreciated.

You can install the PECL extension stats and then use the stats_standard_deviation() function to compute the standard deviation. Also look at http://php.net/manual/en/function.stats-standard-deviation.php for a pure PHP implementation (if you do not want to install the extension).

Related

Select a sum in Knex.js without using .raw

I am trying to rewrite some MySQL queries in Knex.js, and I feel like I'm running into .raw at every turn, which feels counter to the reason I want to use Knex in the first place.
Is it possible to write the following query without using .raw?
SELECT
product,
SUM(revenue)
FROM orders
Using raw, it works to write:
knex()
.select(
'product',
knex.raw('SUM(revenue)')
)
.from('orders')
but the idea of using Knex was to avoid using MySQL query strings, so I'm hoping there's another way. Or does everyone just use .raw everywhere, and I'm misunderstanding something? Very possible, I'm new to this.
You can use the sum method.
sum — .sum(column|columns|raw) Retrieve the sum of the values of a
given column or array of columns (note that some drivers do not
support multiple columns). Also accepts raw expressions.
knex('users').sum('products')
Outputs:
select sum("products") from "users"
Probably be something like this:
knex()
.select('product')
.sum('revenue')
.from('orders')
You should adjust to your specific case. You might need to use something like groupBy('product') to get total revenue per product.
You should really go over knex's documentation, it's pretty good and straight forward and you definitely should not be using raw all the time.
You can even specify the returning sum column name like this:
knex(tableName)
.select('product')
.sum({ total: 'revenue' })
.groupBy('product');

Cron Bash - select data from two MySQL tables & export to CSV

I am really bad at creating MySQL queries and need some help. I need to create a bash file to be triggered by a cron job once a week - that queries two tables, grabbing data where the user IDs match in both tables, and adding the select data to a CSV export file. I would like the CSV to be comma separated. Right now the best I can get it tab separated.
My issue in getting this query to run is my syntax (which I know is wrong as I have simply stolen snippets from various articles online). I did get each DB query to work separately (grabbing from one table with one query and another table with another query). Now I need to combine them to grab only the data I need.
Here's my current (non working) query:
#!/bin/bash
mysql -u USERNAME --password=PASSWORD --database=xxxx_DBNAME --execute='SELECT `xxxx_videotraining_user.user_id`, `xxxx_videotraining_user.training_title`, `xxxx_videotraining_user.status`, `xxxx_users.id`, `xxxx_users.name`, `xxxx_users.user_employer`, `xxxx_users.user_ss_number` WHERE `xxxx_videotraining_user.user_id` = `xxxx_users.id` AND `xxxx_videotraining_user.status` = "Completed" AND `xxxx_users.user_ss_number` > "1" ORDER BY `xxxx_videotraining_user.user_id` LIMIT 0, 10000 AND ' -C > /home/xxxx/subs/vtc/DB_EXPORTS/xxxx_videotraining_completed.csv
I think you can see what I am trying to accomplish here - any help would be greatly appreciated!
It also looks like you're missing your FROM clause, have an trailing AND clause (as noted in other answers), and are quoting things incorrectly. This looks to be your original query:
SELECT `xxxx_videotraining_user.user_id`,
`xxxx_videotraining_user.training_title`,
`xxxx_videotraining_user.status`,
`xxxx_users.id`,
`xxxx_users.name`,
`xxxx_users.user_employer`,
`xxxx_users.user_ss_number`
WHERE `xxxx_videotraining_user.user_id` = `xxxx_users.id` AND
`xxxx_videotraining_user.status` = "Completed" AND
`xxxx_users.user_ss_number` > "1"
ORDER BY `xxxx_videotraining_user.user_id`
LIMIT 0, 10000 AND
I think you want to add the FROM clause, quote the table and field separately, and remove the trailing AND, to get something like:
SELECT `xxxx_videotraining_user`.`user_id`,
`xxxx_videotraining_user`.`training_title`,
`xxxx_videotraining_user`.`status`,
`xxxx_users`.`id`,
`xxxx_users`.`name`,
`xxxx_users`.`user_employer`,
`xxxx_users`.`user_ss_number`
FROM `xxxx_users`,
`xxxx_videotraining_user`
WHERE `xxxx_videotraining_user`.`user_id` = `xxxx_users`.`id` AND
`xxxx_videotraining_user`.`status` = "Completed" AND
`xxxx_users`.`user_ss_number` > "1"
ORDER BY `xxxx_videotraining_user`.`user_id`
LIMIT 0, 10000
There are other things that could be done to shorten the size of the query and make it a bit cleaner, but that should get it functional.
One thing I know that helps me when dealing with long queries is to format them like this, with the main clauses separated out so you can see the different sections of the query.
Let me know if that helps.
I think AND shouldn't be here:
LIMIT 0, 10000 AND

SELECT n-th row WHERE field = x value

format(sql, sizeof(sql), "SELECT * FROM `datab` WHERE License = %s", searchPlate);
Querying with this format will give me all the rows with this result, but what i'm trying to do is take for ex. the third or fifth or even tenth row that has this result, not all of the rows. How can i do this?
Something like this should work in MySQL:
format(sql, sizeof(sql), "SELECT * FROM `datab` WHERE License = %s ORDER BY IDColumnNameGoesHere LIMIT %d, 1", searchPlate, MyDesiredRowInteger);
Some points:
%d might not be right, use the correct symbol for an integer.
You are most definitely using a specific RDBMS, you must look into the documentation and find out. SQL is a standard, MySQL ans SQL-Server etc are implementations of that standard. You must find out which implementation you are using.
Sticking variables into strings like you have done leaves you very vulnerable to SQL injection. You should always parameterize your queries.
LIMIT is specific to MySQL if you are using a different RDBMS you will have to go another route. For example SQL-Server you can use TOP, but as this only has one parameter you will need to use min or max in addition to only get the one record you desire.

MySQL using table columns in function to create alias to be used in sorting

It sounds more complicated than it actually is. Here is what I'm trying to do within the SELECT part:
SELECT TIMESTAMPADD(
UCASE(
SUBSTRING(offset_unit,1,CHAR_LENGTH(offset_unit)-1)
),1,'2003-01-02') as offset_date
offset_unit is a VARCHAR column in the database. It contains one of the following: "Hours","Minutes".
offset is an INT.
I am trying to convert the offset_unit to uppercase, after I have removed the last character ('s') so I can have a proper interval (MINUTE, HOUR...) so I can get a date that I can use in sorting afterwards, but MySQL keeps throwing an error. I have tested each step by adding one function at a time, and it only fails after I add TIMESTAMPADD. If I enter MINUTE manually then it works.
Any way to get this working?
Additional info: I am running this in CakePHP 1.3, in a find, within the 'fields' array, but that shouldn't be important.
this can be easily achived by using CASE WHEN clause as:
SELECT (CASE
WHEN offset_unit = 'HOURS'
THEN TIMESTAMPADD(HOUR,`offset`,'2003-01-02')
WHEN offset_unit = 'MINUTES'
THEN TIMESTAMPADD(MINUTE,`offset`,'2003-01-02')
END) AS offset_date
FROM my_table;
SEE SQLFIDDLE DEMO HERE
It doesn't work because TIMESTAMPADD does not take a string as the first argument, but a unit keyword, for example MINUTE. My guess is that you need to do this in two steps, first get the unit and then construct a query with the correct keyword.

Mysql is not counting the rows of dates from my php script

I am trying to count the number of dates that occur for a specific mem_id, however, my count output is always "0"... heres my code:
$datechecker = $postdate;
//$postdate is a date variable that is posted via a form into mysql, stored as a DATE
$sql = mysql_query("SELECT * FROM members WHERE mem_id='$id' AND postdate='$datechecker'");
$Counter = mysql_num_rows($sql);
if($Counter >= 0) {
echo "$datechecker $Counter";
exit();
}
This is the output I get: 2011-01-01 0
Even though I have about 10 occurrences of 2011-01-01, so why does my count say "0"? Can anyone help me solve this, or provide an alternate?
echo the string before you mysql_query it, this will validate if the query is what you expect it to be. You can also use count(*) within the query, instead of using php's mysql_num_rows()
I also hope that you're sanitising your input before you're querying that!
1) You didn't clean $postdate, who knows if it conforms to MySQL's definition of DATE?
2) You didn't show us how your members table looks like. Is mem_id primary key? If it is, then of course you're going to get 1 row out of it.
3) You aren't checking whether your query succeeds or not, you immediately pass the resource_id to the mysql_num_rows table - which is a wrong way to perform counting anyway because MySQL (like any other relational database) has inbuilt mechanisms of counting rows based on criteria.
My guess is that your query is failing, seeing there's not $id specified.