In MySQL I need to retrieve artist with highest points by location - php

In MySQL I need to get artist with highest points by location. Please help.
user_location_tbl (user location table)
|--------------------------------------|
| countryLat | countryLong | userid |
|--------------------------------------|
| 31.695766 | 54.624023 | 1 |
| 20.593684 | 78.96288 | 2 |
| 20.593684 | 78.96288 | 3 |
| 20.593684 | 78.96288 | 4 |
| 31.695766 | 54.624023 | 5 |
|--------------------------------------|
fans_table (to view which artist has which user as a fan)
|----------------------|----------
| artist_id | user_id | Points |
|----------------------|----------
| 1 | 1 | 20 |
| 1 | 2 | 30 |
| 2 | 1 | 40 |
| 2 | 3 | 40 |
| 3 | 1 | 60 |
|----------------------|----------
artist_table (list of artist)
|-------------------|
| artistid | name |
|-------------------|
| 1 | raja |
| 2 | sekar |
| 3 | thomas |
|-------------------|
I need to get location wise which artist is having highest point but I can't do it in a single query. If I put sum(points) and group by countryLat, countryLong, artistid, I get the following result...
|---------------------------------|
| 100 | 20.593684 | 78.96288 | 1 |
| 50 | 20.593684 | 78.96288 | 2 |
| 100 | 31.695766 | 54.624023 | 3 |
| 90 | 31.695766 | 54.624023 | 1 |
|---------------------------------|
...but I only need the artist with highest point on that location as in the example below...
|---------------------------------|
| 100 | 20.593684 | 78.96288 | 1 |
| 100 | 31.695766 | 54.624023 | 3 |
|---------------------------------|
SQL
SELECT Sum(c.tot_points),
a.artist_id
FROM `fans_table` AS a
INNER JOIN `user_location_tbl` AS b
ON a.user_id = b.user_id
INNER JOIN artist_table AS c
ON a.artist_id = c.id
GROUP BY b.countrylat,
b.countrylong,
a.artist_id
Above is my query

So assuming I understand your question right you want to get which artist has the most points for each location so this would be the process to figure it out manually:
// First we add up all the points for each artist in each location:
|----------------------------------------------|
| Points | countryLat | countryLong | artistid |
|----------------------------------------------|
| 30 | 20.593684 | 78.96288 | 1 |
| 40 | 20.593684 | 78.96288 | 2 |
| 0 | 20.593684 | 78.96288 | 3 |
| 20 | 31.695766 | 54.624023 | 1 |
| 40 | 31.695766 | 54.624023 | 2 |
| 60 | 31.695766 | 54.624023 | 3 |
|----------------------------------------------|
// Then we get the max for each location
|----------------------------------------------|
| Points | countryLat | countryLong | artistid |
|----------------------------------------------|
| 40 | 20.593684 | 78.96288 | 2 |
| 60 | 31.695766 | 54.624023 | 3 |
|----------------------------------------------|
The query to do this is as follows
SELECT artist_id, ul.countryLat, ul.countryLong, max_points
FROM fans_table f
JOIN user_location_tbl ul
ON ul.userid = f.user_id
JOIN (
SELECT countryLat, countryLong, MAX(f.total_points) max_points
FROM
(SELECT artist_id, countryLat, countryLong, SUM(Points) as total_points
FROM fans_table f
JOIN user_location_tbl ul
ON ul.userid = f.user_id
GROUP BY artist_id, countryLat, countryLong) f
GROUP BY countryLat, countryLong) p
ON p.countryLat = ul.countryLat
AND p.countryLong = ul.countryLong
GROUP BY f.artist_id, ul.countryLat, ul.countryLong
HAVING p.max_points = SUM(Points)

Making an assumption that the points in an area will be unique (ie, either there won't be 2 equally popular artists in an area, or if there are you want them both) then something like the following will do it
SELECT Sub3.artist_id, Sub3.countryLat, Sub3.countryLong, Sub2.MaxArtistLocalPoints
FROM
(
SELECT a.artist_id, countryLat, countryLong, SUM(a.Points) AS ArtistLocalPoints
FROM `fans_table` AS a
INNER JOIN `user_location_tbl` AS b ON a.user_id=b.user_id
INNER JOIN artist_table AS c ON a.artist_id=c.id
GROUP BY a.artist_id, countryLat, countryLong
) Sub3
INNER JOIN
(
SELECT countryLat, countryLong, MAX(ArtistLocalPoints) AS MaxArtistLocalPoints
FROM
(
SELECT a.artist_id, countryLat, countryLong, SUM(a.Points) AS ArtistLocalPoints
FROM `fans_table` AS a
INNER JOIN `user_location_tbl` AS b ON a.user_id=b.user_id
INNER JOIN artist_table AS c ON a.artist_id=c.id
GROUP BY a.artist_id, countryLat, countryLong
) Sub1
) Sub2
ON Sub3.countryLat = Sub2.countryLat
AND Sub3.countryLong = Sub2.countryLong
AND Sub3.ArtistLocalPoints = Sub2.MaxArtistLocalPoints

Related

Join 3 tables; select a list from specific group

I have 3 tables
Table#1: groups
|---------------|---------------|
| id_group | Name |
|-------------------------------|
| 1 | Group 1 |
--------------------------------|
| 2 | Group 2 |
--------------------------------|
| 3 | Group 3 |
--------------------------------|
Table#2: jobs
|---------------|---------------|----------------------|
| id_job | id_group | name_job |
|---------------|--------------------------------------|
| 1 | 1 | name_1 |
-------------------------------------------------------|
| 2 | 1 | name_2 |
-------------------------------------------------------|
| 3 | 2 | name_3 |
-------------------------------------------------------|
| 4 | 3 | name_4 |
-------------------------------------------------------|
| 5 | 3 | name_5 |
-------------------------------------------------------|
| 6 | 3 | name_6 |
-------------------------------------------------------|
Table#3: users
|---------------|---------------|
| user | id_job |
|-------------------------------|
| A | 1 |
--------------------------------|
| B | 1 |
--------------------------------|
| C | 4 |
--------------------------------|
| D | 6 |
--------------------------------|
If I were an user (e.g C), the result I'd look for is a page where there is a table with 2 columns (USERS | JOB).
The column USERS should be filled in with all the users who share the same group. The column JOB should be filled in with all name_job of the specific group group as follows:
LOGIN: C
|---------------|---------------|
| user | job |
|-------------------------------|
| C | name_4, |
| | name_5, |
| | name_6 |
--------------------------------|
| D | name_4, |
| | name_5, |
| | name_6 |
--------------------------------|
I tried with this code, but the result is that I can read people who share the same group with me, but I can't read the jobs.
SELECT users.* jobs.*
FROM users JOIN jobs ON users.id_job=jobs.id_job
WHERE job.id_group IN
(SELECT job.id_group
FROM users JOIN jobs ON users.id_job = jobs.id_job
WHERE users.user= '$login')
Your help is appreciated in advance.
If I follow you correctly, you want the list all jobs of the group the user belongs to. One option uses a correlated subquery and string aggregation:
select u.*,
(
select group_concat(j1.name_job order by j1.id_job)
from jobs j
inner join jobs j1 on j1.id_group = j.id_group
where j.id_job = u.id_job
) as job_names
from users u

MySQL getting total number of enquiries for each branch

I have three tables and they are the following
User Table
+---------+-----------+--------+
| user_id | user_name | branch |
+---------+-----------+--------+
| 1 | John | 1 |
| 2 | Jim | 2 |
| 3 | Jern | 3 |
| 4 | Jack | 1 |
| 5 | Jery | 2 |
| 6 | Tom | 3 |
| 7 | Sona | 1 |
| 8 | Tina | 3 |
+---------+-----------+--------+
Branch Table
+-----------+----------------+
| branch_id | branch_name |
+-----------+----------------+
| 1 | IT |
| 2 | SALES |
| 3 | Administration |
+-----------+----------------+
Enquiry Table
+------------+---------------+---------+
| enquiry_id | enquiry_name | user_id |
+------------+---------------+---------+
| 1 | enqury_test1 | 1 |
| 2 | enqury_test2 | 2 |
| 3 | enqury_test3 | 1 |
| 4 | enqury_test4 | 3 |
| 5 | enqury_test5 | 2 |
| 6 | enqury_test6 | 5 |
| 7 | enqury_test7 | 1 |
| 8 | enqury_test8 | 2 |
| 9 | enqury_test9 | 4 |
| 10 | enqury_test10 | 6 |
| 11 | enqury_test11 | 2 |
| 12 | enqury_test12 | 7 |
+------------+---------------+---------+
From the above tables its clear that, each branch contains a number of users.
These users post multiple enquiries.
I need to get the total number of enquiries in each branch as
branch id => number of enquiries
I have tried various queries. But i couldn't get the result. Any one can help?
I am using MySQL and i need a single query to do this.
Thanks in advance
You need count and group by
select
b.branch_id,
count(e.user_id) as `total_enq`
from Branch b
left join User u on u.branch = b.branch_id
left join Enquiry e on e.user_id = u.user_id
group by b.branch_id
The query you have to perform to get you desired result is like this :-
$query = "SELECT u.branch, COUNT(u.user_id) AS `total_enquires`
FROM enquiry e INNER JOIN user u ON e.user_id = u.user_id
GROUP BY u.branch"
This will help you,and i think you don't need to join branch table as user table already contain branch_id.
This is the query
SELECT `branch`,`branch_name`,count(`user`.`user_id`),count(`enquiry_id`) FROM `user` inner join `branch` on `user`.`branch`=`branch`.`branch_id` inner join `enquiry` on `user`.`user_id`=`enquiry`.`user_id` group by `branch`
try it here
http://sqlfiddle.com/#!9/cf3eb/1
SELECT
bt.branch_id
,COUNT(enquiry_id) AS total_enquiry
FROM
enquiry_table et
INNER JOIN user_table ut on ut.user_id = et.user_id
INNER JOIN branch_table bt ON bt.branch_id = ut.branch
WHERE
1=1
GROUP BY
bt.branch_id
you can try this

MYSQL: subquery return as table name in join

Is it possible to use subquery return as a table name in join?
Dynamic Table(dynamictable)
+--------+--------------+----------+-----------+--------+
| tableid| tablename | settings | pack_type | status |
+--------+--------------+----------+-----------+--------+
| 24 | xxxxxx | NULL | F | A |
| 25 | YYYYYY | NULL | M | A |
| 30 | ZZZZZZ | NULL | M | A |
| 26 | AAAAAA | NULL | M | A |
+--------+--------------+----------+-----------+--------+
Product Table(products)
+--------------+------------+
| tableid | product_id |
+--------------+------------+
| 30 | 1 |
| 30 | 2 |
| 25 | 3 |
| 30 | 4 |
+--------------+------------+
xxxxxx
+------------+--------------+
| product_id | product_cost |
+------------+--------------+
| 1 | 350 |
| 2 | 200 |
| 4 | 200 |
+------------+--------------+
i.e(for example):
select *
from products as p
left join (select tablename
from dynamictable as d
where d.tableid = p.tableid) as dt
on dt.product_id = p.product_id;
You need to use LEFT JOIN into subquery.
select *
from products as p
left join (select tablename,products.tableid
from dynamictable as d
left join products on d.tableid = products.tableid
) as dt
on dt.product_id = p.product_id;

SQL query statement table joins

I have a problem with a SQL query and the resultset being returned not being what I expected.
I have these three tables that I am trying to relate.
events_detail
__________________
| ID | start_date |
| 1 | 2012-08-09 |
| 2 | 2013-02-13 |
| 3 | 2012-12-12 |
| 4 | 2013-01-21 |
| 5 | 2012-12-25 |
-------------------
where ID is the primary key
events_category_relationship
__________________________
| ID | event_id | cat_id |
| 1 | 1 | 1 |
| 2 | 2 | 4 |
| 3 | 3 | 2 |
| 4 | 4 | 2 |
| 5 | 5 | 3 |
--------------------------
where ID is primary key
events_category_detail
__________________________________
| ID | name | description |
| 1 | Europe | Kings and castles! |
| 2 | USA | Freedoms |
| 3 | China | Made in China |
| 4 | UK | Big Brother |
------------------------------------
where ID is primary key
What I need to do is grab only 1 event from each category and sorted by date of earliest appearance. So what I should expect in my result is the following
Result Set
________________________________________________________________
| e_id | start_date | c_id | category_name | category_desc |
| 1 | 2012-08-09 | 1 | Europe | Kings and castles! |
| 3 | 2012-12-12 | 2 | USA | Freedoms |
| 5 | 2012-12-25 | 3 | China | Made in China |
| 2 | 2013-02-13 | 4 | UK | Big Brother |
-----------------------------------------------------------------
My SQL query that I tried looks like this
SELECT e.id, e.start_date, c.category_name, c.category_desc
FROM events_detail e
JOIN events_category_relationship r ON r.event_id = e.id
JOIN events_category_detail c ON c.id = r.cat_id
ORDER BY date(e.start_date)
This just joins the 3 tables and returns the result in order by date. What I am stuck on is making it so that only one of each category is displayed like the desired result set above. I have tried using DISTINCT c.category_name and GROUP BY c.category_name, but none of them works.
Any help or advice will be greatly appreciated.
You will want to use a subquery to get the min(start_date) for each name and description. You will then use this result to join back to your events_details table to get the id associated with the data in the subquery:
SELECT e.id,
d.start_date,
d.name,
d.description
FROM events_detail e
INNER JOIN
(
select min(e.start_date) Start_date,
c.name,
c.description
from events_detail e
INNER JOIN events_category_relationship r
ON r.event_id = e.id
INNER JOIN events_category_detail c
ON c.id = r.cat_id
group by c.name, c.description
) d
on e.start_date = d.Start_date
ORDER BY date(e.start_date)
See SQL Fiddle with Demo

mysql inner join 2 tables and order by count

I am having the following tables in my DB
PROJECTS
+----+-------------------------------------------+
| id | name |
+----+-------------------------------------------+
| 1 | YANNONALI COURT |
| 2 | UNIVERSITY OF COLORARDO DENVER RESEARCH 2 |
| 3 | G.R.E.A.T PROGRAM DESALTER BUILDING |
| 4 | MONARCH CLUB |
| 5 | LAFAYETTE MERCANTILE |
| 6 | CAMELBACK VILLAGE RAQUET AND HEALTH CLUB |
| 7 | BACK COUNTRY |
| 8 | URBAN CRASHPAD |
| 9 | PRIVATE RESIDENCE |
| 10 | EATON RESIDENCE |
+----+-------------------------------------------+
PROJECT_ASSIGNMENTS(WHERE projects.id=project_assignment.target_id)
+-------+-----------+-------------+
| id | target_id | property_id |
+-------+-----------+-------------+
| 19178 | 1 | 48 |
| 19192 | 1 | 39 |
| 19391 | 1 | 3 |
| 19412 | 2 | 3 |
| 19591 | 2 | 34 |
| 19610 | 2 | 34 |
| 21013 | 3 | 2 |
| 21032 | 3 | 2 |
| 30876 | 4 | 2433 |
| 38424 | 5 | 2580 |
+-------+-----------+-------------+
PROPERTIES(WHERE properties.id= project_assignment.property_id)
+----+------------------+
| id | name |
+----+------------------+
| 2 | Residential |
| 3 | Multi Family |
| 34 | New Construction |
| 39 | Contemporary |
| 48 | Southwest |
+----+------------------+
I want O/P ordered by no.of projects in the list...
Residential(177) //12 - total no.of projects which is having this property
Multi Family(15)
New Construction(13)
Contemporary(11)
please give me some MySQL queries
Thank You
This should do the trick:
select
c.name,
count(c.id) as CountOfProperties
from
projects a,
project_assignments b,
properties c
where
a.ID=b.target_id
and b.property_id=c.ID
group by
c.name
order by
count(c.id) desc;
Try this::
select
prop.name,
count(prop.id) as CountOfProperties
from
projects p
inner join project_assignments pa on (p.ID=pa.target_id)
inner join properties prop on (pa.property_id=prop.ID)
group by
prop.name
order by
count(prop.id) desc;

Categories