Order by inside loop PDO [duplicate] - php

I have a table which stores IDs and the city where the store is located.
I want to list all the stores starting with the stores that are in the city where there are the most stores.
TABLE
ID CITY
1 NYC
2 BOS
3 BOS
4 NYC
5 NYC
The output I want is the following since I have the most stores in NYC, I want all the NYC location to be listed first.
1 NYC
4 NYC
5 NYC
2 BOS
3 BOS

SELECT count(City), City
FROM table
GROUP BY City
ORDER BY count(City);
OR
SELECT count(City) as count, City
FROM table
GROUP BY City
ORDER BY count;
Ahh, sorry, I was misinterpreting your question. I believe Peter Langs answer was the correct one.

This one calculates the count in a separate query, joins it and orders by that count (SQL-Fiddle):
SELECT c.id, c.city
FROM cities c
JOIN ( SELECT city, COUNT(*) AS cnt
FROM cities
GROUP BY city
) c2 ON ( c2.city = c.city )
ORDER BY c2.cnt DESC;

This solution is not a very optimal one so if your table is very large it will take some time to execute but it does what you are asking.
select c.city, c.id,
(select count(*) as cnt from city c2
where c2.city = c.city) as order_col
from city c
order by order_col desc
That is, for each city that you come across you are counting the number of times that that city occurs in the database.
Disclaimer: This gives what you are asking for but I would not recommend it for production environments where the number of rows will grow too large.

SELECT `FirstAddressLine4`, count(*) AS `Count`
FROM `leads`
WHERE `Status`='Yes'
AND `broker_id`='0'
GROUPBY `FirstAddressLine4`
ORDERBY `Count` DESC
LIMIT 0, 8

Related

MySQL formatting results based on table name and multiple table data

I am coming into this project and have a little MySQL background to do basic SELECTs and INSERTs and whatnot. But, this is making me beat my head against the wall.
I have a typical user information table in MySQL:
USERS
+-------+----------+---------+-----+
|user_id|first_name|last_name|email|
+-------+----------+---------+-----+
1 tim jones tj#acme.com
2 sarah peteres sp#acme.com
3 larry doe ld#acme.com
Then I have multiple product tables:
PRODUCTS_ONE
+-------+-------+---------+----------+--------------+
|prod_id|user_id|prod_name|prod_width|prod_ship_date|
+-------+-------+---------+----------+--------------+
1 1 bowl nine 1-1-16
2 1 fork one 1-2-16
3 2 plate eleven 1-3-16
PRODUCTS_TWO
+-------+-------+----------+--------+--------------+
|prod_id|user_id|prod_state|prod_job|prod_ship_date|
+-------+-------+----------+--------+--------------+
1 3 maine min 1-1-16
2 2 texas max 1-2-16
3 1 ohio min 1-1-16
I have 15 total PRODUCT tables that all have prod_id, users_id, and prod_ship_date. The other fields might all be different based on what product table they are in. But, all the different PRODUCT tables have those three common fields.
What I am trying to accomplish is to get a list of USER info and PRODUCT info for products that match a certain ship date.
I want to find all the users and what product table and product id they are getting on a certain date.
So, if I searched on a ship date of 1-1-16, I would get something like:
+----------------+-----------+-------------+-----------+
|users.first_name|users.email|product_table|products_id|
+----------------+-----------+-------------+-----------+
tim tj#acme.com one,two 1,3
larry ld#acme.com one 3
If I searched on a ship date of 1-2-16, I would get something like:
+----------------+-----------+-------------+-----------+
|users.first_name|users.email|product_table|products_id|
+----------------+-----------+-------------+-----------+
tim tj#acme.com one 2
sarah sp#acme.com two 2
I hope this all makes sense. Unfortunately, I cannot change the structure or layout of the various product tables due to legacy issues.
I just can't figure out the MySQL statement to use to get something like this.
The above results will be used for reporting purposes.
you could write a query like this:
select first_name,email,prod_id,group_concat(product_table) as product_table from (
select u.user_id ,first_name,email,prod_id, 'one' as product_table from users u join products_one p on u.user_id = p.user_id where prod_ship_date = '2016-01-01 00:00:00'
union
select u.user_id,first_name,email,prod_id, 'two' as product_table from users u join products_two p on u.user_id = p.user_id where prod_ship_date = '2016-01-01 00:00:00'
) a
group by a.user_id
order by user_id,product_table
and so on.
With the second group concat and order by
select first_name,email,group_concat(prod_id),group_concat(product_table) as product_table from (
select u.user_id ,first_name,email,prod_id, 'one' as product_table from users u join products_one p on u.user_id = p.user_id where prod_ship_date = '2016-01-01 00:00:00'
union
select u.user_id,first_name,email,prod_id, 'two' as product_table from users u join products_two p on u.user_id = p.user_id where prod_ship_date = '2016-01-01 00:00:00'
) a
group by a.user_id
order by user_id,product_table
Check out this sqlfiddle

how should i do this query in mysql

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.

MySQL Group running too slow

I have a 3 MySQL tables which I need to get results from and which are:
1. Towns
Fields Towncode and Townname
2. Students
Fields student_id,name,surname,address,streetcode,towncode,HeadOfFamily
3. Phonebank
Fields student_id,contacted,towncode
Now I need a mysql statement (a) to get the total number of households from the students table and also (b) the number of students contacted for that particular town.
up to step (a) I managed which and is extremely fast which is:
SELECT
t.towncode as towncode,
t.townname as townname,
(SELECT COUNT(*)
FROM students p
WHERE p.towncode=t.towncode
and p.student_hh='H') AS households
FROM
towns t
ORDER BY
t.towncode ASC
but I cannot manage to insert as well another SELECT STATEMENT to get the number of calls fr that particular town.
Can you kindly assist please?
Doing a per-record count on towns is probably hurting you. I would pre-query the students table first, THEN use that joined to the towns.
For indexes, I would have the following indexes
table index
towns ( towncode, townname )
students ( student_hh, towncode )
SELECT
t.towncode as towncode,
t.townname as townname,
TownCnts.households
FROM
towns t
JOIN ( SELECT
p.towncode,
COUNT(*) households
from
students p
where
p.student_hh = 'H'
group by
p.towncode ) as TownCnts
ON t.towncode = TownCnts.towncode
ORDER BY
t.towncode ASC
Assuming that the number of "calls" is the number of rows in the PhoneBank table with a particular town code, then you can add another subselect:
SELECT t.towncode as towncode, t.townname as townname,
(SELECT COUNT(*)
FROM students p
WHERE p.towncode = t.towncode and p.student_hh='H'
) AS households,
(SELECT COUNT(*)
FROM phonebank pb
WHERE pb.towncode = t.towncode
) AS calls
FROM towns t
ORDER BY t.towncode ASC ;
Your question is a little vague. It is possible that you want count(distinct studentid) in the second query, rather than count(*).
To optimize this query, create the following indexes:
towns(towncode)
students(towncode, student_hh)
phonebank(towncode)

How to compare tabels and get difference out

I have some problems to compare two of my tables. Usually I show my attempt how to solve a problem but here I do not know what to do. Normally, I do it in php. So i get all the information from 2 tables and then compare. But I would like to do it in MySQL. I hope you can help.
The first table, is my transactions table. This is the place where people have used their cards in restaurants.
The second table is my booking table. This is the place where people book reservations in restaurant.
I want to compare these tables, so i can get those who has NOT used their reservation
Transaction mySQL
SELECT t.*, em.* FROM transactions as t
left join exp_members as em on (t.cardid-10000000 = em.member_id)
left JOIN exp_member_data emd on em.member_id = emd.member_id ORDER BY t.created DESC
Transaction Table.
Trans_ID TransactionTime Name Restaurant
1852 2013-04-08 12:45:21 Christian La Canton
1851 2013-04-08 12:41:00 Zaz Parken
Booking mySQL
SELECT b.* from exp_menucard_booking as b;
Booking Table:
ID BookingTime Name NumberOfPeople Restaurant
270 2013-04-09 14:45:00 Christian 2 La Canton
269 2013-04-08 12:17:00 Toby 4 La Raz
As you can se, Toby from Booking table has not used his card (transaction tabel). How can i get him out of my tabel.
If you want to select all persons, who have already booked (there is an entry in booking table) but do not have an entry in the Transaction Table you could try this query:
SELECT *
FROM `Booking` B
WHERE NOT EXISTS (
SELECT *
FROM `Transaction` T
WHERE T.name = B.name
);
BTW it would be better, if you used some User_ID instead of name to identify the persons
This is how you can select all the records that didn't use the booking. It's called an excluding left join or left exclude join. http://www.magecorner.com/mysql-joins-explained/
I'm not sure if this would be faster than WHERE NOT EXISTS, but considering that has a subquery, I think this is faster.
SELECT emb.*
FROM exp_menucard_booking emb
LEFT JOIN transactions t
ON (
t.Name = emb.Name AND
t.Restaurant = emb.Restaurant
)
WHERE t.Trans_ID IS NULL
SELECT * FROM Booking WHERE NAME NOT IN (SELECT NAME FROM Transaction );

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