SQL SELECT row with highest value where problem_id is the same - php

I'm working on a project where I have to list the solutions with the highest votes per problem.
Every problem has two solutions and the users can vote on one solution per problem. This is my database at the moment.
+----------+------------+---------+
| id | id_problem | vote |
+----------+------------+---------+
| 1 | 1 | 25 |
| 2 | 1 | 10 |
| 3 | 2 | 18 |
| 4 | 2 | 2 |
| 5 | 3 | 6 |
| 6 | 3 | 7 |
| 7 | 4 | 11 |
| 8 | 4 | 4 |
| 9 | 5 | 5 |
| 10 | 5 | 2 |
+----------+------------+---------+
I would like to get this result:
(The row with the highest vote per id_problem)
+----------+------------+---------+
| id | id_problem | vote |
+----------+------------+---------+
| 1 | 1 | 25 |
| 3 | 2 | 18 |
| 6 | 3 | 7 |
| 7 | 4 | 11 |
| 9 | 5 | 5 |
+----------+------------+---------+

SELECT
id,
id_problem,
max(vote)
from
tablename
group by
id_problem
order by
id_problem ASC
The max(vote) determines greater vote, but it aggregate the result, then you need to group by id_problem and then order it asc.

You can use group by clause with max aggregation function to get the expected result, e.g.:
select id, id_problem, max(vote) as vote
from result
group by id_problem
order by id_problem
Here's SQL Fiddle.

Related

Find the ranking for Concatenated rows in mysql

I have a table with concatenated values within both rows, I am therefore uniquely retrieve ranking for each row in the tables.
UPDATE
The other tables has been added to question
NamesTable
NID | Name |
1 | Mu |
2 | Ni |
3 | ices |
GroupTable
GID | GName |
1 | GroupA |
2 | GroupB |
3 | GroupC |
MainTable
| NID | Ages | Group |
| 1 | 84 | 1 |
| 2 | 64 | 1 |
| 3 | 78 | 1 |
| 1 | 63 | 2 |
| 2 | 25 | 2 |
| 3 | 87 | 2 |
| 1 | 43 | 3 |
| 2 | 62 | 3 |
| 3 | 37 | 3 |
Now the first Name is equated to the first age in the table, I am able to equate them using php and foreach statements, Now the problem is with the ranking of the ages per each group. I am ranking the names uniquely on each row or group.
Results which is expected
| Names | Ages | Group | Ranking |
| Mu,Ni,ices | 84,64,78 | 1 | 1,3,2 |
| Mu,Ni,ices | 63,25,87 | 2 | 2,3,1 |
| Mu,Ni,ices | 43,62,37 | 3 | 2,1,3 |
In my quest to solving this, I am using GROUP_CONCAT, and I have been able to come to this level in the below query
SELECT
GROUP_CONCAT(Names) NAMES,
GROUP_CONCAT(Ages) AGES,
GROUP_CONCAT(Group) GROUPS,
GROUP_CONCAT( FIND_IN_SET(Ages, (
SELECT
GROUP_CONCAT( Age ORDER BY Age DESC)
FROM (
SELECT
GROUP_CONCAT(Ages ORDER BY Ages DESC ) Age
FROM
`MainTable` s
GROUP by `Group`
) s
)
)) rank
FROM
`MainTable` c
GROUP by `Group`
This actually gives me the below results.
| Names | Ages | Group | Ranking |
| 1,2,3 | 84,64,78 | 1 | 7,9,8 |
| 1,2,3 | 63,25,87 | 2 | 5,6,4 |
| 1,2,3 | 43,62,37 | 3 | 2,1,3 |
The only problem is that the ranking Values increase from 1 to 9 instead of ranking each row uniquely. Its there any idea that can help me cross over and fix this? I would be grateful for your help. Thanks

GROUP BY with active record?

I have a table (url_analyst) with the following info:
id | user_id | url_id | date | visits
----------------------------------------------------
1 | 2 | 5 | 2015-10-25 | 15
2 | 2 | 6 | 2015-10-25 | 18
3 | 2 | 5 | 2015-10-25 | 11
4 | 3 | 8 | 2015-10-25 | 22
5 | 3 | 9 | 2015-10-27 | 30
6 | 5 | 15 | 2015-10-25 | 15
etc
What I want is a update/insert earning in a new table "earning"
earning calculate 1$/10 visits
id | user_id | total_urls | date | total_visits | earning
-------------------------------------------------------------------
1 | 2 | 3 | 2015-10-25 | 44 | 4.4$
2 | 3 | 1 | 2015-10-25 | 22 | 2.2$
3 | 3 | 1 | 2015-10-27 | 30 | 3.0$
4 | 5 | 1 | 2015-10-25 | 15 | 1.5$
How can I do this with CodeIgniter using the active record query method? Can this be done with COUNT Total URL then GROUP BY user_id AND Date , update earning?
Try this MySQL query:
SELECT
user_id, count(url_id), date, sum(visits) as
total_visits, concat(sum(visits)/10,'$') as earning
FROM
url_analyst
GROUP BY
user_id, date
Considering all group_by columns from url_analyst table,
$this->db->select("SUM(total_url)");//if required select other fields
$this->db->group_by("url_analyst.user_id");
$this->db->group_by("url_analyst.date");
If you want group_by on any column from earning, you can change the table name in group_by clause

Reorder rows within groups

I am making a management system for a site that has a bunch of image galleries. The interface will allow the user to add, delete, or reorder images within each gallery.
I have a table for all the images across all galleries together, with 'id' auto-incremented, and default for sort_order set to 0.
+----+-----------+------------+------------+
| id |gallery_id | sort_order |
+----+-----------+------------+------------+
| 1 | 1 | 1 |
| 2 | 1 | 0 |
| 3 | 1 | 2 |
| 4 | 1 | 3 |
| 5 | 1 | 4 |
| 6 | 1 | 5 |
| 7 | 1 | 6 |
| 8 | 2 | 0 |
| 9 | 2 | 1 |
| 10 | 2 | 2 |
| 11 | 2 | 3 |
| 12 | 2 | 4 |
| 13 | 2 | 5 |
| 14 | 2 | 6 |
+----+-----------+------------+------------+
Here is the reorder query, using a serialized array via ajax:
if($_POST['item']) {
$order = 0;
foreach ($_POST['item'] as $id) {
$rearrange = $db->query
("UPDATE images SET sort_order = '".$order."' WHERE id = '".$id."'");
$order++;
It limits sort_order according to the length of the array that is passed, and then defaults to 0 for the next group its comes to. I can reorder, add, delete, and it always restricts changes to the gallery_id group I am editing.
(As an experiment, I inserted sort_order values ascending across all galleries, like this:
+----+-----------+------------+------------+
| id |gallery_id | sort_order |
+----+-----------+------------+------------+
| 1 | 1 | 0 |
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 1 | 4 |
| 5 | 1 | 5 |
| 6 | 1 | 6 |
| 7 | 1 | 7 |
| 8 | 2 | 8 |
| 9 | 2 | 9 |
| 10 | 2 | 10 |
| 11 | 2 | 11 |
| 12 | 2 | 12 |
| 13 | 2 | 13 |
| 14 | 2 | 14 |
+----+-----------+------------+------------+
And when I reordered rows using my interface, it limited the sort_order within gallery_id groups, exactly as shown in the first table).
I'm looking for caveats to this approach. Anyone done it this way?
UPDATE images
SET
sort_order = FIELD(id, A, B, C, D, E)
WHERE gallery_id = N
AND id IN(A, B, C, D, E)
I do it the same way, but I actually put the image inserted last by calculating the number of rows in each gallery. When a user wants to order he has to filter the list for a specific gallery first then he can sort the images in the gallery.
I cannot but point out the terrible security issues with your code. I really, really, really hope that you are not actually writing the queries like that as anybody can easily do whatever they want with your database.
http://xkcd.com/327/ comes to mind. If I submit an item like 0'; drop table images; your entire table is gone.

SELECT records WHERE rows have difference on a specific column

I have a database table campaign_data. I need to select the customer_id where in the campaign there is difference in tariff. How can i do that with MySQL query. Here is some sample data.
SQL Fiddle Schema
| CAMPAIGN_ID | CUSTOMER_ID | CAMPAIGN_NAME | TARIFF |
---------------------------------------------------------
| 1 | 1 | Richmond | 100 |
| 2 | 1 | Sutton Coldfield | 75 |
| 3 | 1 | Putney | 100 |
| 4 | 1 | Kentish Town | 100 |
| 5 | 1 | Woking | 100 |
| 6 | 2 | Chiswick | 90 |
| 7 | 2 | Ealing | 100 |
| 8 | 2 | Camden | 100 |
| 9 | 3 | Croydon | 75 |
| 10 | 3 | Croydon1 | 100 |
| 11 | 3 | Archway | 100 |
| 12 | 4 | Ealing0 | 100 |
| 13 | 4 | Ealing01 | 100 |
| 14 | 4 | Ealing02 | 100 |
| 15 | 4 | Chingford | 100 |
| 16 | 4 | chingford01 | 100 |
Now as you can see customer id 1 , and 3 has different tariffs. I want to select them and leave the customer id 4 because it has campaigns with same tariffs.
Desired Output
| CUSTOMER_ID |
---------------
| 1 |
| 2 |
| 3 |
For clearification you can see customer 1 has 5 records. If in his 5 records the tariff is same (100) i want to avoid but if the tariff is not some as 4 records have 100 and one has 75, i want to select.
SELECT customer_id, count(DISTINCT tariff) as tariffs
FROM campaign_data
GROUP BY customer_id
HAVING tariffs > 1
you looking for this maybe
SELECT customer_id
FROM campaign_data
GROUP BY customer_id
HAVING count(DISTINCT tariff) > 1
http://sqlfiddle.com/#!2/48b6e/31
select
customer_id,
tariff
from campaign_data
group by customer_id
having sum(tariff)/count(tariff) <> tariff;

select data from database Mysql query

tbl_pack_service;
+-------+---------+------------+
| ps_id | pack_id | service_id |
+-------+---------+------------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 1 |
| 4 | 2 | 2 |
| 5 | 2 | 3 |
| 6 | 2 | 4 |
| 7 | 2 | 5 |
| 8 | 3 | 1 |
| 9 | 3 | 2 |
| 10 | 3 | 3 |
| 11 | 3 | 4 |
+-------+---------+------------+
ps_id is primary key
i am tying to make dynamic select list in php
i want a mysql query that can give service id which do not match with particular pack_id
like i have service_id 1,2,3,4,5
when i should select pack_id=1 then 3,4,5 should be displayed
and when i should select pack_id=2 then nothing should be displayed as it has all the 5 services.
thanks..
There are a few ways to handle this. The easiest is with a NOT IN subquery:
SELECT DISTINCT service_id
FROM
tbl_pack_service
WHERE service_id NOT IN (SELECT service_id FROM tbl_pack_service WHERE pack_id = 1)

Categories