how should i do this query in mysql - php

I want to do the following. I have a table in the database, I am working on a table called asistencia and this table has 3 columns
id_asistencia as a int AUTOINCREMENT
nro_matricula as an int which I took it from another table called
alumnos
fecha as a date
This is a sketch of the database
id_asistencia | nro_matricula | fecha
1 | 0001| 2015-01-10
2 | 0002| 2015-01-10
3 | 0002| 2015-02-10 (another date )
The thing is I have to do a percentage
select all id_1 records in my nro_matricula column and see how many times its repeated in my rows and do a percentage respect all the dates in my database
EG : id_1 came to class day(whatever day) and he/she did not came to class the next day so id_1 has 50% assistance
Expected result
nro_matricula | percentage
0001| 50
0002| 100
The question is how can I make this query. If can be done in PHP its even better but i feel that this can be done in SQL
PS : The Database wasn't created by me
And excuse my English is not the better and i expect it to be understandable for you to help me

You can use sql statement like this:
select (
sum (if nro_matricula = '001' ,1,0 )
/ count(*)
from asistencia
--where nro_matricula = '001'

Maybe just simply:
select al.nro_matricula,
100 * count(distinct al.fecha) / (select count(distinct al1.fecha) from alumnos al1) as percentage
from alumnos al
group by al.nro_matricula

I did found the answer to my question. Thank you all for helping me out
SELECT
asistencia.nro_matricula as matricula,
COUNT( DISTINCT asistencia.fecha)* 100 /
COUNT( DISTINCT asistencia.nro_matricula) / (SELECT COUNT(DISTINCT asistencia.fecha)
FROM asistencia
ORDER BY COUNT(*) DESC
LIMIT 1 )
as porcentaje_asistencia
FROM asistencia
JOIN alumno
WHERE asistencia.nro_matricula = alumno.nro_matricula AND alumno.id_curso = 'basica6a'

Tried this in Oracle. Should work in MySQL too.
SELECT aa.NRO_MATRICULA , days_present/total_count* 100 FROM
(SELECT DISTINCT NRO_MATRICULA,
COUNT(*) as days_present FROM ASISTENCIA GROUP BY NRO_MATRICULA ) AA
,
(SELECT COUNT(*) as total_count FROM (SELECT DISTINCT(FECHA) FROM ASISTENCIA GROUP BY FECHA)) BB
Ouptut
nro_matricula percentage
0001 50
0002 100
The query (SELECT COUNT(*) FROM (SELECT DISTINCT(FECHA) FROM ASISTENCIA AA GROUP BY FECHA)) will give count of distinct date (2 in your case). Then we are getting distinct nro_matricula group by nro_matricula to get its count which will give the days it was present. Then divide both values from above steps to get percentage.

Related

combine two tables and sum mysql

i want to join two tables but i can't do it as i want to sum column and get the result between two dates
first table named : vip_allotment_details
allotment_id qty
2 3
2 5
1 2
1 4
the second table name : vip_allotment
id date_from date_to
1 2017-10-1 2017-10-5
2 2017-10-6 2017-10-10
what i want from the query to get me this result
id qty date_from date_to
1 6 2017-10-1 2017-10-5
2 8 2017-10-6 2017-10-10
i will explain the result :
first allotment_id field is linked with id field in second table , the result i want that we can make sum of qty by the two fields (id , allotment_id ) between the date_from and date_to
and here is my try :
$query1 = "
SELECT SUM(qyt) as total
FROM vip_allotment_details
where allotment_id IN ( SELECT id from vip_allotment where date_from >= '$date_1' AND date_to <= '$date_2')
";
In my query the result gets all the sum of qty field with no filter ..
I hope I have explained my problem well .
thanks/.
I'm not try yet, but maybe you can try like this:
SELECT a.id AS id, SUM(qyt) AS qty, date_from, date_to
FROM vip_allotment AS a
LEFT JOIN vip_allotment_details AS b on b.allotment_id = a.id
WHERE a.date_from >= '{thedatestart}' AND a.date_to <= '{thedateend}'
GROUP BY a.id
ORDER BY a.id ASC;
You need to use JOIN. I see you are using IN keyword, which won't work. There can be many ways to solve your problem. One of them is,
select allotment_id, qty, date_from, date_to
from
(select allotment_id, SUM(qty) as qty
from vip_allotment_details group by allotment_id
) at
INNER JOIN
vip_allotment va
ON va.id= at.allotment_id;
I think the following should do what you ask.
SELECT
va.id,
SUM(vad.qyt) AS total,
va.date_from,
va.date_to
FROM vip_allotment_details AS vad
LEFT JOIN vip_allotment AS va ON va.id = vad.allotment_id
GROUP BY vad.allotment_id
Try below.i think you will get your desired result.
select va.id, temp.qty , va.date_from,va.date_to from vip_allotment as va
inner join (select sum(qty) as qty , allotment_id from vip_allotment_details group by `allotment_id`) as temp
ON temp.allotment_id=va.id
where va.date_from >= '$date_1' AND va.date_to <= '$date_2';
If you want more then one result form an aggregate function (SUM, COUNT, AVG, ...) you'll need to use a GROUP BY. Your query isn't that hard, this should do the trick:
SELECT va.id, va.date_from, va.date_to, SUM(vad.qyt) AS qyt
FROM vip_allotment AS va
LEFT JOIN vip_allotment_details AS vad ON vad.allotment_id = va.id
GROUP BY va.id
And as you can see here, this produces the expected result: http://sqlfiddle.com/#!9/707a8/2
If you now want to start adding extra filters (like filter by date), you can just do so by adding a WHERE to the query. Something like this:
...
LEFT JOIN ...
WHERE va.date_from >= "2017-10-06" and va.date_to <= "2018-10-06"
GROUP BY ...
http://sqlfiddle.com/#!9/707a8/6
On a side note, I noticed you are not binding your params in the php part of your code . Do note that this can pose serious security issues, especially if these dates come directly from the user input. I would suggest looking in to PDO to do the actual querying in PHP.
Try this..change your table name and run the query..hopefully it should give the result as your requirement..if not let me know...
select a.id
, sum(b.qty)
, a.date_from
, a.date_to
from table1 a
, table2 b
where a.id = b.allotment_id
group
by b.allotment_id

get all rows having common parents

id parent_id child_id
1 1 1
2 2 2
3 2 2
4 1 1
I have a table from which i need to get the common values from data when i query it with id... for eg if id=2 and id=3 then return
id parent_id
2 2
3 2
i have tried this after hunting a lot through various examples :
SELECT ta.user_id,ta.interest_parent_id,ta.interest_child_id
FROM user_interest ta
WHERE ta.user_id=2 AND
(SELECT COUNT(*) FROM user_interest tb
WHERE ta.interest_parent_id=tb.interest_parent_id
AND tb.user_id=3 )>1
but it responds with only:
id parent_id
2 2
any help :( im using a mysql database with php/codeigniter to do the scripting
You can give it a try:
SELECT
tOne.id,
tOne.parent_id
FROM
(
SELECT
*
FROM user_interest A
WHERE A.id IN (2,3)
) tOne
INNER JOIN
(
SELECT
*
FROM user_interest A
WHERE A.id IN (2,3)
) tTwo
ON tOne.parent_id = tTwo.parent_id
AND tOne.id <> tTwo.id
ORDER BY tOne.parent_id;
SQL FIDDLE DEMO
Any suggestion towards optimization of the query is welcome.
EDIT: SQL FIDDLE
You can make a sub SELECT:
SELECT * FROM table WHERE Name IN (SELECT Name FROM table GROUP BY Name HAVING count(*) > 1)

Select account_id by max Date

Hello I have the following table design
ID account_id score date
------------------------------------------
1 500 4 x
2 764 4 x
3 500 6 x
4 500 7 x
5 764 5 x
I'm trying to get all rows with the latest account_id entry
so my code should return
ID account_id score date
------------------------------------------
4 500 7 x
5 764 5 x
I tried the following code but it seems to return the first entry but with the latest date
SELECT account_id,score, max(date) from table group by account_id
Case 1: If id is auto-increment column or max(id) means latest row.
select * from
(select * from table_name
order by id desc) temp
group by account_id
Case 2: If date column decides latest row then replace id by date in order clause and group clause.
try it-
SELECT distinct a.id,a.account_id,b.score,b.date
FROM mytable b
JOIN
(
SELECT account_id,MAX(id) AS id
FROM mytable
GROUP BY account_id
) a ON a.account_id=b.account_id
ORDER BY a.id;
This question is just a duplicate of SQL Select only rows with Max Value on a Column
There you'll find a good explanation.
SELECT a.*
FROM table a
INNER JOIN (
SELECT `account_id`,MAX(`date`) AS latest FROM table GROUP BY account_id
) b
ON a.`date` = b.`latest` AND a.`account_id` = b.`account_id`
ORDER BY `date` DESC
Reference :
Using ORDER BY and GROUP BY together
Try using this query it works fine
Select a.account_id,a.score,a.date
from authors as a
join
(Select account_id,max(date) as date
from authors
group by account_id) as d
on(d.date=a.date)

sql query to calculate sum of agroup counts

fields id ,party,votes
my query getting o/p like this
partyname bjp aap congress
votes 1 2 2
but i also need sum of votes. below is my expected output.
BJP aap congress total
1 2 2 5
SELECT RES.PARTYNAME, COUNT( RES.CONSTITUENCY )
AS VOTESCOUNT FROM voter_count RES JOIN (SELECT CONSTITUENCY, MAX( VOTES )
AS VOTES FROM voter_count GROUP BY CONSTITUENCY)MAXS USING ( VOTES, CONSTITUENCY )
GROUP BY PARTYNAME LIMIT 0 , 1000";
Take a look at this
SELECT SUM(something) AS something, SUM(else) AS else FROM stuff
Just an idea how you can get the SUM
According to your table,
SELECT SUM(partyname) AS total_parties, SUM(votes) AS total_votes FROM table_name;
is this what you want?? Your question is not clear & query is irrelavant to description...

MySQL query: generate a report of the top votes for the each food type

I have a user table with id, username and food_id columns. The idea is the user stored their favorite food and we come up with a league table of foods and I want to generate a report of the top votes for the each food type. I am using MySQL and PHP.
For clarity, here is an example of the table:
id food_id username
1 1 Bob
2 100 Jane
3 200 Andy
4 1 Maggy
5 100 Rich
6 100 Mick
7 1 Kevin
How do I write the query to list the foods that have the most votes. I want to limit the result to x number, say top 100. In this case I want the result to be as follows:
food_id score
1 3
100 4
I hope the question is clear enough. The query is beyond me but I am sure it must be possible to do it using DISTINCT and COUNT in some way or other. Perhaps it's sub queries?
select food_id, count(*) score
from myTable
group by food_id
order by score desc limit 100
SELECT F.food_name,
COUNT(*) AS score
FROM myTable AS M
INNER JOIN food_table AS F
ON F.food_id = M.food_id
GROUP BY F.food_name
ORDER BY score DESC limit 100
select count(*) as top100 from table group by food_id order by top100 desc limit 100
SELECT f.`food_id`, COUNT(*) AS `count`
FROM `fav_food_table` f
GROUP BY f.`food_id`
ORDER BY `count` DESC
LIMIT 100;

Categories