MySQL temporary table - php

In the project I'm working I use php language and mysql database.
The reason I thought to use temporary tables was right is because I perform many calculations, and in javascript they would take me a long time.
I must show these tables at screen:.
Table 1:
Total data. | 6
Average. | 2984-99
Sum x-Media. | 5088.9
Sum (x-Media)^2. | 138092659.8396
Sum (x-Media)^4. | 1.09E+16
Maximum value. | 9812.12
Minimum value. | 18.23
Table 2:
Amount | x-Media | (x-Media)^2 | (x-Media)^4
839.12 | -2145.87 | 704122.3744 | 495788318130.694
18.23 | 18.23 | 332.3329 | 110445.15642241
9812.12 | 11957.99 | 96277698.8944 | 9.27E+15
23.93 | 5.7 | 572.6449 | 327922.18149601
863.21 | -11094.78 | 745131.5041 | 555220958402.328
6353.33 | 6347.63 | 40364802.0889 | 1.63E+15
All calculations are based on the amount column, this value. I get it from the table tbl_layout_c:
Amount decimal (18,2)
----------
839.12
18.23
9812.12
23.93
863.21
6353.33
So the query is:
1 SELECT amount
2 (SELECT COUNT(*) FROM tbl_layout_c ) AS total_data
3 (SELECT SUM(amount) FROM tbl_layout_c ) AS total_sum,
4 (SELECT total_sum / total_data AS average,
5 (SELECT amount - average ) AS x_media,
6 (SELECT SUM(x_media)) AS suma_x_media
7 FROM tbl_layout_c
The issue is at LINE 6: (SELECT SUM(x_media)) AS suma_x_media
because I get the same value as x_media column. Ex:
Amount | x-Media | Sum x-Media.
839.12 | -2145.87 | -2145.87
And I need:
Amount | x-Media | Sum x-Media.
839.12 | -2145.87 | 5088.9
I have trouble when I try to use function sum() in the temporary column (suma_x_media) of the temporary table.. It's not working, I just get the same value as x_media
Anyone have any idea what I'm missing?
Here you can see an example of the Code

try this
select *,sum(x_media) from (SELECT monto, #obtengo el campo monto
(SELECT COUNT(*) FROM tbl_layout_c ) AS total_datos, #contar los registros
(SELECT SUM(monto) FROM tbl_layout_c ) AS suma_total, #suma total
(SELECT MAX(monto) FROM tbl_layout_c ) AS valor_maximo, #valor maximo
(SELECT MIN(monto) FROM tbl_layout_c ) AS valor_minimo, #valor minimo
(SELECT suma_total / total_datos) AS promedio, #promedio
(SELECT monto - promedio) AS x_media #media artimetica
FROM tbl_layout_c)tablealias
I tried in sql Fiddle with your data and It works. your sum(x_media) is 0 with data in sql Fiddle you have if you change the data same as here in TABLE 2 then you can get expected output same mentioned in Table 1.

Related

MySQL - Average of Unique rows

If I have three columns:
id, user, points
My data is:
+-------+------------------+-------------+
| id | user | points |
+-------+------------------+-------------+
| 1 | A | 100 |
+-------+------------------+-------------+
| 1 | A | 200 |
+-------+------------------+-------------+
| 2 | B | 300 |
+-------+------------------+-------------+
| 2 | B | 400 |
+-------+------------------+-------------+
I would like to have the average of ONLY the max points of each user.
For this exmple I want to get as results: 300 points ((200+400)/2).
When I use the following Mysql query, I get: 250:
SELECT avg(points) FROM table
SQL DEMO
Try this :
SELECT avg(points) FROM (
SELECT max(points) as points FROM table1 group by id
) as T
Firstly get the max points of each user and then get the AVG from them.
You should first get the max group by use and the the avg of this subquery
SELECT AVG(points)
FROM (SELECT MAX(points) FROM your_table GROUP BY user) subt

Get the total of multiple column in sql

In database I have such table:
| id hotel_id | room_id | Ac_rooms | Non_ac_rooms | simple_rooms | Furnitured_room | other_rooms | added_by |
| 9 | 2 | 3 | 2 | 6 | 12 | 21 | raj |
I want to get the total numbers of room from SQL query (which is the total of room_id, Ac_rooms, Non_ac_rooms, simple_rooms, Furnitured_room, other_rooms).
What is the best way to get the total from SQL query? I need total number of rows.
Try this:
SELECT
SUM(Ac_rooms) as Ac_rooms,
SUM(Non_ac_rooms) as Non_ac_rooms,
SUM(Simple_rooms) as Simple_rooms,
SUM(Furnitured_rooms) as Furnitured_room,
SUM(Other_rooms) as Other_rooms,
SUM(Ac_rooms+Non_ac_rooms+Simple_rooms+Furnitured_room+Other_rooms) as Total_rooms,
FROM tbl_rooms
Or
SELECT
SUM(SUM(Ac_rooms)+SUM(Non_ac_rooms)+SUM(Simple_rooms)+SUM(Furnitured_room)+SUM(Other_rooms)) as Total_rooms,
FROM tbl_rooms
If I understood you correctly, you just need the sum
select (ac_rooms + Non_ac_rooms + simple_rooms + Furnitured_room + other_rooms) as total_rooms from YOUR_TABLE
Also you specified finding total number of rows, which you can get by using standart count function
select count(*) as number_of_rows from YOUR_TABLE
Or may be you are looking for the sum of types of the rooms through all the rows? In that case you will need
select sum(ac_rooms ), sum(Non_ac_rooms), sum(simple_rooms), sum(Furnitured_room), sum(other_rooms) from YOUR_TABLE
UPD: If I got you right, you need this
select sum(ac_rooms ) as ac_rooms_total,
sum(Non_ac_rooms) as non_ac_rooms_total,
sum(simple_rooms) as simple_rooms_total,
sum(Furnitured_room) as furnitured_room_total,
sum(other_rooms) as other_rooms_total,
sum(ac_rooms + Non_ac_rooms + simple_rooms + Furnitured_room + other_rooms) as TOTAL
from YOUR_TABLE

Display only first of duplicate column values

How to query for erase the view below?
+-------------------+------------+
| Order_id | Weight |
| 20 | 4 |
| 21 | 5 |
| 22 | 2 |
| 22 | 2 |
+-------------------+------------+
To be like this:
+-------------------+------------+
| Order_id | Weight |
| 20 | 4 |
| 21 | 5 |
| 22 | 2 |
| 22 | |
+-------------------+------------+
When displaying results but not entered into the database.
A simple way is:
select DISTINCT order_id, weight from xyz
UNION
select order_id, null from xyz
group by order_id, weight
having count(*) > 1
Order by weight desc;
The 1st select statement will display all the unique values and 2nd one will retrieve only the repeated values.
In your required output table, it seems like you want to display all the non-repeated rows and the 1st column value of repeated rows but not 2nd column value. The above query will allow you to do that.
OK, here is how to do it:
SELECT
Order_id,
Weight,
if(#order_id = Order_id, '', Weight) as no_dup_weight,
#order_id := Order_id as dummy
FROM Table1
ORDER BY Order_id asc;
You basically need to check to see if the previous Order_id is the same as the current, and if they are, output an empty field.
Here is an SQLFiddle demonstrating the solution.
Do you actually need 2 rows for the dupes? Can't you just use the DISTINCT clause as per http://www.mysqltutorial.org/mysql-distinct.aspx
Or is it important to know what has duplicates. In which case you should look into the GROUP BY clause

MySQL Multiple Conditions on Group By / Having Clause

I have three tables that are all inter-related with the following structure.
ModuleCategory Table:
+------------------+----------------+------------+
| ModuleCategoryID | ModuleCategory | RequireAll |
+------------------+----------------+------------+
| 90 | Cat A | YES |
| 91 | Cat B | NO |
+------------------+----------------+------------+
ModuleCategorySkill Table:
+------------------+---------+
| ModuleCategoryID | SkillID |
+------------------+---------+
| 90 | 1439 |
| 90 | 3016 |
| 91 | 1440 |
| 91 | 3016 |
+------------------+---------+
EmployeeSkill Table:
+---------+---------+
| EmpName | SkillID |
+---------+---------+
| Emp1 | 1439 |
| Emp1 | 3016 |
| Emp2 | 1440 |
| Emp2 | 3016 |
| Emp3 | 1439 |
| Emp4 | 3016 |
+---------+---------+
Desired Output:
+------------------+-------+
| ModuleCategory | Count |
+------------------+-------+
| Cat A | 1 |
| Cat B | 3 |
+------------------+-------+
I am trying to group by ModuleCategoryID's and get the count of employees which have the skills being tracked.
Normally, I can do the following query to obtain the numbers:
select mc.ModuleCategory, Count(*) as Count from ModuleCategory as mc
join ModuleCategorySkill as mcs on mc.ModuleCategoryID = mcs.ModuleCategoryID join EmployeeSkill as es on es.SkillID= mcs.SkillID
group by mc.ModuleCategoryID
However, I have a column RequireAll in the ModuleCategory table which if it is set to 'YES' should only count employees as 1 only if they have all the skills in the category. If it is set to NO then it can count each row normally and increase the count by the number of rows it groups by.
I can achieve this by writing separate queries for each modulecategoryID and using a having Count() > 1 (which will find me anyone that has all the skills for ModuleCategoryID 90). If there were 3 skills than I would have to change it to Having Count() > 2. If there isn't anyone that has all the skills specified, the count should be 0.
I need a dynamic way of being able to do this since there is a lot of data and writing one query for each ModuleCategoryID isn't the proper approach.
Also, I am using PHP so I can loop through and create a sql string that can help me achieve this. But I know I will run into performance issues on big tables with a lot of skills and modulecategoryID's.
Any guidance on how to achieve this is much appreciated.
You can do it by joining on the total category counts, and then using conditional aggregation:
select modulecategory,
count(case when requireall = 'yes'
then if(s = t, 1, null)
else s
end)
from (
select modulecategory,empname, requireall, count(*) s, min(q.total) t
from employeeskill e
inner join modulecategoryskill mcs
on e.skillid = mcs.skillid
inner join modulecategory mc
on mcs.modulecategoryid = mc.modulecategoryid
inner join (
select modulecategoryid, count(*) total
from modulecategoryskill
group by modulecategoryid
) q
on mc.modulecategoryid = q.modulecategoryid
group by modulecategory, empname
) qq
group by modulecategory;
demo here
This operates under the assumption an employee isn't going to be allocated the same skill twice, if that is something that may happen, this query is alterable to support it, but it seems like a broken scenario to me.
What we have here is an inner query that collates all the information we need (category name, employee name, whether or not all skills are required, how many skills are in the group per employee, and how many there in the group total), with an outer query that uses a conditional count to change how the rows are tallied, based on the value of requireall.

How to get unique result from below entry?

plan_id | elementclass | table_no | ress_id | UserID | Status
1 | elementclass1 | 1 | 0 | 0006100022 | N
1 | elementclass1 | 1 | 2 | 0006100022 | N
1 | elementclass2 | 2 | 0 | 0006100021 | N
1 | elementclass4 | 3 | 0 | 0006100023 | N
in above row I am expecting as this
if row is having same elementclass,table_no but different ress_id in that condition only take that row which is non zero.If with above condition tow rows having 0 it can take any row .if both rows have non zero then also it can take any one.
Now
for rest of others it can take values with 0.We can use group by to plan_id as there may be multiple plans.
Desired result
plan_id | elementclass | table_no | ress_id | UserID | Status
1 | elementclass1 | 1 | 2 | 0006100022 | N
1 | elementclass2 | 2 | 0 | 0006100021 | N
1 | elementclass4 | 3 | 0 | 0006100023 | N
Please help.
thanks
SELECT * FROM TableName a
WHERE a.ress_id = (SELECT MAX(b.ress_id) FROM TableName b WHERE b.table_no = a.table_no)
GROUP BY a.plan_id,a.table_no
This gives you:
1 result per plai_id and table_no
each result has biggest ress_id in it
First get the maximum ress id per element class. Then select the related records. There may be duplicates. Hence group by element class and ress id.
The following statement does not precisely do what you asked for, but maybe it suffices. In case of a tie you won't get one of the records, but one of the records' plan ids, one of the records' table nos, one of the records' user ids and one of the records' statusses. So the user id may be taken from one record and the status from another when elementclass and ress_id are equal.
select plan_id, mytable.elementclass, table_no, mytable.ress_id, userid, status
from mytable
join
(
select elementclass, max(ress_id) as max_ress_id
from mytable
group by elementclass
) agg on agg.elementclass = mytable.elementclass and agg.max_ress_id = mytable.res_id
group by mytable.elementclass, mytable.ress_id;
(It is possible to write a statement to access complete records in case of ties, but this is much more complicated - at least in MySQL.)
Try this:
SELECT T1.*
FROM TableName T1 JOIN
(SELECT elementclass,table_no,MAX(ress_id) as ress_id
FROM TableName
GROUP BY elementclass,table_no
)T2 ON T1.elementclass=T2.elementclass AND T1.table_no=T2.table_no AND T1.ress_id=T2.ress_id
Explanation:
Here, we are creating a temporary table T2 with maximum of ress_id for each elementclass and table_no. Then we join this table with the original table with these 3 fields and select all records from the original table T1.
Result:
PLAN_ID ELEMENTCLASS TABLE_NO RESS_ID USERID STATUS
-------------------------------------------------------------------
1 elementclass1 1 2 0006100022 N
1 elementclass2 2 0 0006100021 N
1 elementclass4 3 0 0006100023 N
See result in SQL Fiddle.

Categories