Group by with count not working Mysql Php - php

I have two tables "employer" and "user", and i want to get total user(according to country) Where "skills" and "entity" column
matches (like query) with both table
Table employer
id skills entity
1 Php,Design web
Table user
id skills entity country
33 programming,php web india
44 Graphic designing,php design canada
45 Php web india
46 Dot net test Sri Lanka
Now i want to get result like
id Count country
1 2 india
2 1 canada
i am trying with following query but not working for me, where i am wrong ?
SELECT employer_info.id as employer_id,users_info.country,COUNT(users_info.country) as total
FROM employer_info
JOIN users_info ON employer_info.skills=users_info.skills
GROUP BY users_info.country

If you want to count the number of users in a country by employer, you should count the number of user ids and not the country.
As for the GROUP BY, this should be done on the non-aggregated fields, which are the employer_info.id and users_info.country
SELECT employer_info.id as employer_id,users_info.country,
COUNT(users_info.id) as total
FROM employer_info
JOIN users_info
ON employer_info.skills=users_info.skills
GROUP BY employer_info.id, users_info.country

Try this one:
SELECT A.id as employer_id,B.country,COUNT(B.country) as total
FROM employer_info A
JOIN users_info B ON A.skills=B.skills AND A.entity=B.entity
GROUP BY A.id, B.country

Related

sticky rows : fetching some rows always on top of list in postgresql

Im fetching records from a table, say countries, I always need few rows on top(in first of result set)
ID country
--------------------------
1 China
2 Japan
3 Taiwan
4 USA
5 Germany
6 Brazil
7 India
--------------------------
I want to keep Japan and China in the list top and then sort the rest
so the result set always should be
----------------------
Japan
China
next country
next country
next country
next country
----------------------
is there any way to do this using CTE or any other way that is right for this requirement?
Im using PostgreSQL 9.4
You can just pick those two countries out then add rest of them, something like:
select * from table
where country ='China' or country = 'Japan'
union select * from table;
union already remove the duplicated rows for you.
Hope this helps.
I use this order by technique in mysql but should work in postgresql just as well.
SELECT * FROM table ORDER BY FIELD(country, 'Japan', 'China') DESC;
One oddity or illogical bit at least in mysql is the query above will list China then Japan then all the rest.
You can achieve this objective using following query:
select your_column_list,
(CASE country WHEN 'Japan' THEN 0 WHEN 'China' THEN 1 ELSE 2 END) AS nu
from your_table_name
ORDER BY nu ASC
It depends where is kept the information of the sticky countries.
If this information is kept directly in the country table, since true > false you can just ORDER BY is_sticky DESC, country_name ASC
If this information is filled by the user and you know the country_id, then you can leverage the use of VALUES to keep the wanted countries on top list:
SELECT
label
FROM
country
LEFT JOIN (VALUES (3), (4)) ontop (label_id) USING (label_id)
ORDER BY
ontop.label_id IS NOT NULL DESC,
label ASC
Of course you could JOIN directly on the country name but that is slower.

PHP/MySQL - Count number of sales made and display that number and who sold them

I'm working on a PHP application for University which pretends I buy and resell a specific item to/from countries.
I have a table which contains transaction IDs and the names of the countries that made them.
I've been trying to count up the number of times a specific country's name appears in the database table then print out a table on the webpage showing each countries name and the number of times they appear in the table like below, but I can't find any examples of this kind of thing anywhere, they're always too different to be of much help. I would also like to order the table by max to min count and also be able to limit the number of countries shown using radio buttons (which I've already got working).
countryName | numberOfSales
Belize | 10
Brazil | 6
Cameroon | 64
Colombia | 23
Costa Rica | 47
You need to select the country and count, then group by the country. If you want to order it you need to add that on as well.
SELECT
countryName,
count(*) as numberOfSales
FROM
sales
GROUP BY
countryName
ORDER BY
numberOfSales DESC
This query will have 2 columns in the results. The country names and the number of times they appear according to the grouping. We are grouping all of the records by the country name column. In the query, we name the column numberOfSales, so we can use that when ordering it so that the countries will be in order from max to min in numberOfSales.
If you have two tables in your database (MySql in my case), one where you store the different countries and one for the sales/orders.
Table countries:
id INT
country VARHCAR(255)
Table: sales:
id INT
country_id INT
title VARCHAR(255)
Here there is a 1:many relationship between the two tables. One country can have many sales, but a sale can only belong to one country.
You can then fetch the number of sales for specific country by running the following SQL query.
If you want to find the number of sales for Denmark you could do:
SELECT countries.country, COUNT(*) AS numberOfSales
FROM countries
JOIN sales
ON sales.country_id = countries.id
WHERE countries.country = 'denmark';
If you want to see the total number of sales for each country you can use the following SQL query:
SELECT countries.country, COUNT(*) AS numberOfSales
FROM countries
JOIN sales
ON sales.country_id = countries.id
GROUP BY countries.country;
Here the GROUP BY clause will fetch the result for each of the countries in your countries table. You can add LIMIT clause if necessary.
I hope this doesn't complicate things too much. You will thank me later by using two tables (I do not know if you already do. If you do, NICE).
Related to counting identical rows in MySql: Count number of identical rows in MySQL with PHP
Best regards.

Display Null Elements

I have a table for students (containing a foreign key referencing school) and a table for schools.
I would like display list the Schools in London and total students in each school.
SQL Code is:
SELECT
sc.id_school,
sc.name,
count(*) as count
FROM
students as st
INNER JOIN
schools as sc
ON
sc.id_school=st.id_school
WHERE
sc.city='London'
GROUP BY
sc.name
The result is:
id_school name count
2 Gateway 4
3 St Peters 3
The result however does not display Schools in London that do not have listed students.
I would want the result to show:
id_school name count
2 Gateway 4
7 Manchels 0
1 Rowers 0
3 St Peters 3
4 St Johns 0
Please assist.
You need to use RIGHT join for schools table, so even if there are no students in london schools they will be returned
SELECT
sc.id_school,
sc.name,
count(*) as count
FROM
students as st
RIGHT JOIN
schools as sc
ON
sc.id_school=st.id_school
WHERE
sc.city='London'
GROUP BY
sc.name
You can use LEFT JOIN to display all the rows 'on the left' even if they have no entry in the column 'count'. Same goes for RIGHT JOIN. OUTER JOIN displays all combinations.
To display '0' instead of NULL:
IFNULL(count, 0)
While #MKhalidJunaid provided the correct answer (I already upvoted), I thought I'd offer another answer that more accurately reflects the data but also should be more performant.
SELECT sc.id_school AS School_ID
,sc.name AS School_Name
,COUNT(st.name) AS Student_Count
FROM schools AS sc
LEFT OUTER JOIN students AS st ON sc.id_school = st.id_school
WHERE sc.city = 'London'
GROUP BY sc.id_school,sc.name
By making everything ANSI-compliant (LEFT OUTER JOIN rather than just LEFT JOIN, complete GROUP BY statement), as well as making schools the driver of the query rather than students, you should get the same result set but with some performance gains.
Try to Group by the schoolID
SELECT
sc.id_school,
sc.name,
count(*) as count
FROM
students as st
INNER JOIN
schools as sc
ON
sc.id_school=st.id_school
WHERE
sc.city='London'
GROUP BY
sc.name, sc.id_school;

Join two tables and get the latest date.

Im new to this form and hopefuly I can get some awesome help!
I got three tables
1 "companies"
ID
2 "log"
compid
datum (date)
3 "sales"
datumnow (datetime)
uppdaterad (datetime)
I want to compare log and sales and get the latest or the "newest" entry and display a ASC list of companies from table 1 with only one company for each row. (comparing datum, datumnow & uppdaterad and get the highest date value displayed on one row for each ID from companies)
#RESULT
Rover - 2012-01-15
Daniel - 2012-02-01
Damien - 2012-03-05
I´ve struggled with this for a few days now and can´t get a hold of the solution.
App. ANY help! thanx.
You can use GREATEST() to return the most recent date from those three columns. This assumes you have another column in sales that relates to the other tables. From the structure you show above, the relationship is unclear.
SELECT
companies.ID,
GREATEST(log.datum, sales.datumnow, sales.uppdatedad) AS mostrecent
FROM
companies LEFT JOIN log ON companies.ID = log.compid
/* Assumes sales also has a compid column. Will edit if new info is posted */
LEFT JOIN sales ON companies.ID = sales.compid
WHERE log.userid='$userID' AND sales.seller='$userID'
For only one row with the max date per company, use a MAX() aggregate with a GROUP BY:
SELECT
companies.ID,
MAX(GREATEST(log.datum, sales.datumnow, sales.uppdatedad)) AS mostrecent
FROM
companies LEFT JOIN log ON companies.ID = log.compid
/* Assumes sales also has a compid column. Will edit if new info is posted */
LEFT JOIN sales ON companies.ID = sales.compid
WHERE log.userid='$userID' AND sales.seller='$userID'
GROUP BY companies.ID

need a help with joining multiple tables from SQL in PHP

Let's say I have 3 tables:
Table 1 called "states":
id | state
1 italy
2 netherlands
3 russia
Table 2 called "hotels":
id | hotel name | belongsToCountry
1 Green Hotel 2
2 Luxurious 2
3 Get Warm! 3
Table 3 called "free rooms":
id | roomID | belongsToHotel
1 815 2
2 912 2
3 145 1
4 512 1
5 1200 3
Now, what I need to echo is this:
Netherlands has 4 free rooms.
Russia has 1 free room.
In words:
I need to make a list of all states which have at least 1 free room and I need to return the exact value of how many free rooms there are.
If anyone can help me with this, I'd be so grateful!
Let's build the query step by step.
First, let's assemble the list of hotels and their free room count.
SELECT hotels.id, COUNT(*)
FROM hotels
INNER JOIN free_rooms ON(hotels.id = free_rooms.belongsToHotel)
GROUP BY hotels.id
INNER JOINs force rows from the table on the "left" side of the join (hotels) only to be included in the result set when there is a corresponding table on the "right" (free_rooms). I'm assuming here that there will only be a row in free_rooms when the room is free.
Having this, we can now join against the list-o-nations.
SELECT hotels.id, COUNT(*), states.state
FROM hotels
INNER JOIN free_rooms ON(hotels.id = free_rooms.belongsToHotel)
INNER JOIN states ON(hotels.belongsToCountry = states.id)
GROUP BY hotels.id
It should be noted, by the way, that you've made poor choices in naming these columns. states should be composed of id and state_name, hotels should be id, hotel_name, state_id, and free_rooms should be id, room_name and hotel_id. (I could also argue that states.id should be states.state_id, hotels.id should be hotels.hotel_id and free_rooms.id should be free_rooms.room_id because that makes the joins much easier...)
If you need to represent a "belongs to" relationship, you're actually looking for foreign key restraints. You should use those instead of special naming.
*ahem* Where was I? Oh yes. The second query will result in a result set with three columns - the hotel id, the number of rooms in it, and the country it's in. But, you just need the number of rooms per country, so let's do one last change.
SELECT COUNT(*), states.state
FROM hotels
INNER JOIN free_rooms ON(hotels.id = free_rooms.belongsToHotel)
INNER JOIN states ON(hotels.belongsToCountry = states.id)
GROUP BY states.state
Only two changes. First, we're now grouping together by state. Second, we're no longer including the hotel id in the result set. This should get you the data you need, again assuming that there will never be a row in free_rooms when the room is not free.
raw query - not tested:
SELECT state, COUNT( roomID ) AS rooms
FROM states
INNER JOIN hotels ON belongsToCountry = state.id
INNER JOIN free_rommms ON belongsToHotel = hotels.id
GROUP BY state
SELECT state, COUNT(*) AS nb
FROM states AS S, hotels AS H, rooms AS R
WHERE S.id = H.belongsToCountry
AND H.id = R.belongsToHotel
GROUP BY state
HAVING nb >= 1

Categories