Generic average over multiple entries in a sql column - mysql

I have a SQL table that looks something like this:
| variable | rank |
|__________|______|
| var1 | 0.3 |
| var2 | 0.1 |
| ... | ... |
I have hundreds of entries in the table with multiple instances of every variable with some associated rank. Is there a way I can tell SQL to take the entries for every variable in the first column and output me an average ranking? What I don't want to do is this:
SELECT AVG(column_name)
FROM table_name
WHERE variable=variable_name;
where I would need to specify every single variable.

Yes, it is called GROUP BY:
SELECT variable,AVG(column_name)
FROM table_name
--WHERE variable IN (...) -- you still can filter rows based on variable values
GROUP BY variable

Related

query over 2 columns where value never appears in either column more than once

Looking for a query that takes the following table ProductList
id| column_1 | column_2 | Sum
================================
1 | Product-A | Product-B | 67
2 | Product-A | Product-C | 55
3 | Product-A | Product-D | 23
4 | Product-B | Product-C | 95
5 | Product-C | Product-D | 110
and returns the first record Product-A_Product-B and then skips all records that contain Product-A or Product-B in either column and returns Product-C_Product-D.
I only want to return the row if everything in the row is appearing for the first time.
Assuming that the products don't contain ,, you could use a comma-delimited session variable to store already selected products and check for every row if one of the columns is already contained in that variable:
select column_1, column_2
from (
select l.*,
case when find_in_set(l.column_1, #products) or find_in_set(l.column_2, #products)
then 1
else (#products := concat(#products, ',', l.column_1, ',', l.column_2)) = ''
end as skip
from ProductList l
cross join (select #products := '') init
order by l.id
) t
where skip = 0;
Demo: http://rextester.com/NDVBW87988
But you should know the risks:
ORDER BY in a subquery is not really valid and usually doesn't make sence. The engine may skip it or move it to the outer query.
If you read and write the same session variable in one statement, the execution order is not defined. So the query might not work for all (future) versions.

mysql update multiplecolumns vs compare values in multiple rows

Okay, talking millions of rows here..
Structure of like
EXAMPLE 1
some_data_before this| x_counter_total | y_counter_total | x_counter_week | y_counter_week | x_counter_year | y_counter_year
--------------------------------------------------------------------------------------------------------------------------------------
some_data_here... | 42142142....... | `241242142..... | 23214124...... | .............. | .............. |` ..............
And every of X and Y events to increment these columns vs this
EXAMPLE 2
table A
some_data_before this| x_counter_total | y_counter_total |
----------------------------------------------------------
some_data_here...... | 42142142....... | `241242142..... |
table B
key_connected_with_table_A | x_event | y_event | occured_timestamp
-------------------------------------------------------------------
id 21...................... | true | false | current_timestamp
My need is this. I need number of X and Y events in some time, past day/week/month/year etc.
My question is that Is it better to update(increment) multiple columns describing the time period i need, like in EXAMPLE 1 or is it better to
on each Event add a Row like in EXAMPLE 2 and then count total VOTES with same ID WHERE occured_timestamp - current_timestamo < TIMESTAMP_OF_A_WEEK for example. Which one is more efficient? talking millions of records, and thousands of request in a minute.
NO, I would keep them in a single table since then I would need to fire only one UPDATE statement but if you separate them to 2 tables then either you will need to execute 2 update statement (or) create a AFTER UPDATE TRIGGER to insert into the other table (or) probably do a update join to update all the respective values ion both tables which to me looks more performance hit than having all the columns in single table.

MySQL - GROUP_CONCAT if value is not a substring

I have a column called "Permissions" in my table. The permissions are strings which can be:
"r","w","x","rw","wx","rwx","xwr"
etc. Please note the order of characters in the string is not fixed. I want to GROUP_CONCAT() on the "Permissions" column of my table. However this causes very large strings.
Example: "r","wr","wx" group concatenated is "r,wr,wx" but should be "r,w,x" or "rwx". Using distinct() clause doesn't seem to help much. I am thinking that if I could check if a permission value is a substring of the other column then I should not concatenate it, but I don't seem to find a way to accomplish that.
Any column based approach using solely string functions would also be appreicated.
EDIT:
Here is some sample data:
+---------+
| perm |
+---------+
| r,x,x,r |
| x |
| w,rw |
| rw |
| rw |
| x |
| w |
| x,x,r |
| r,x |
+---------+
The concatenated result should be:
+---------+
| perm |
+---------+
| r,w,x |
+---------+
I don't have control over the source of data and would like not to create new tables ( because of restricted privileges and memory constraints). I am looking for a post-processing step that converts each column value to the desired format.
A good idea would be to first normalize your data.
You could, for example try this way (I assume your source table is named Files):
Create simple table called PermissionCodes with only column named Code (type of string).
Put r, w, and x as values into PermissionCodes (three rows total).
In a subquery join Files to PermissionCodes on a condition that Code exists as a substring in Permissions.
Perform your GROUP_CONCAT aggregation on the result of the subquery.
If it is a case here, that for the same logical entires in Files there exists multiple permission sets that overlaps (i.e. for some file there is a row with rw and another row with w) then you would limit your subquery to distinct combinations of Files' keys and Code.
Here's a fiddle to demonstrate the idea:
http://sqlfiddle.com/#!9/6685d6/4
You can try something like:
SELECT user_id, GROUP_CONCAT(DISTINCT perm)
FROM Permissions AS p
INNER JOIN (SELECT 'r' AS perm UNION ALL
SELECT 'w' UNION ALL
SELECT 'x') AS x
ON p.permission LIKE CONCAT('%', x.perm, '%')
GROUP BY user_id
You can include any additional permission code in the UNION ALL of the derived table used to JOIN with Permissions table.
Demo here

Mysql-Select all tables from a database

I've a database called test and i've tables called x,y,z.
How do i select x,y,z and there is a column called date IN X,Y,Z check whether there is a particular date.
Is there any build in function that does this?
update
SELECT column date from all tables which is in a database called test
Thanks in advance!!
As far as I know, in SQL you cannot 'select a table', you can select some
column(s) from one or many tables at once. The result of such a query is an another table (temporary table) that you retrieve the data from.
Please be more specific about what exactly you want to do (e.g.: "I want to select a column 'z' from table 'tableA' and column 'y' from table 'tableB'") - then I'm sure your question has a pretty simple answer :)
SELECT x.date AS x_date, y.date AS y_date, z.date AS z_date FROM x,y,z;
That produces a result:
+---------+---------+---------+
| x_date | y_date | z_date |
+---------+---------+---------+
| | | |
| | | |
+---------+---------+---------+
Alternatively you can get everything in one column by ussuing a query:
SELECT date FROM x
UNION ALL
SELECT date FROM y
UNION ALL
SELECT date FROM z;
That produces a result:
+-------+
| date |
+-------+
| |
| |
+-------+
In the example above you would get also duplicate values in the single column. If you want to avoid duplicates replace 'UNION ALL' with 'UNION'
I'm still not sure if I undestood what you really want ot achieve, but I still hope that helps
Also take a look at:
http://www.w3schools.com/sql/sql_union.asp
http://www.sql-tutorial.net/SQL-JOIN.asp

mysql query logic

I have an sql query which shows the delivery details of a vehicle. ( it uses greatest to fetch max value from a range of colums for each vehicle stop)
SELECT deliveryid AS deliverynumber, loadid1 AS loadnumberdate,
haulieraccepted AS haulier,
greatest(drop1arrivedatetime, drop2arrivedatetime, drop3arrivedatetime,
drop4arrivedatetime, drop5arrivedatetime) AS planneddate,
date(greatest(ActualDrop1Arrive, ActualDrop2Arrive, ActualDrop3Arrive,
ActualDrop4Arrive, ActualDrop5Arrive )) AS actualenddate,
mitigation
FROM deliverydetails
WHERE deliveryid=44
the output is
deliverynumber | loadnumberdate | haulier | planneddate | actualenddate | mitigation
44 | 484487 | stols transport | 2011-11-26 15:50:00 | 2011-11-26 | customerdelay
How can I add to the mysql query to compare columns 'planneddate' and 'actualenddate'? if the dates are the same then set the query field to 'ontime' else if actualenddate>planneddate then 'deliverylate'. So ideally I want the following output:
deliverynumber | loadnumberdate | haulier | planneddate | actualenddate | mitigation | Status
44 | 484487 | stols transport | 2011-11-26 15:50:00 | 2011-11-26 | customerdelay | ontime.
Thanks for the assistance.
You can use a CASE statement or IF function. Perhaps something like:
SELECT ...., IF(actualenddate>planneddate,'deliverylate','ontime') AS status FROM ....
use mysql if condition and date conversion function to check and display according to....
You can wrap your original query as a subquery. This will rename the columns. Then, use a case ... then clause to add the column.
Assuming your original query works just fine, it would look like this:
select
*,
case when (... some comparison on 'planneddate' and 'actualenddate' ...)
then <true output>
else <false output> end
from
(<your original query>) as myalias;
The trick is that the columns from the subquery are renamed, allowing you to use their new names (planneddate and actualenddate).