Get Highest amount , count of products / users - php

id | user_id | prd_id | amnt | dis
1 | 1 | 10 | 200 | 23
2 | 2 | 10 | 300 | 11
3 | 3 | 20 | 100 | 26
4 | 2 | 20 | 50 | 12
5 | 4 | 30 | 100 | 22
6 | 2 | 40 | 600 | 18
7 | 2 | 30 | 100 | 16
I want 2 result from above table :
First by prod_id as below
prd_id | user_id | cont | highestamt | disc
10 | 2 | 2 | 300 | 11
20 | 3 | 2 | 100 | 26
30 | 4 | 2 | 100 | 22
40 | 2 | 1 | 600 | 18
Second by user_id as below:
user_id | cont | bid on prd_id | winner on bid prod_id |
1 | 1 | 10 | - | -
2 | 4 | 10,20,30,40 | 10,40 |
3 | 1 | 20 | 20 |
4 | 1 | 30 | 30 |
UPDATE : ex: above : user_id = 2 has bid on product 10,20,30,40 ( bid on prd_id ) hence his bidding cont = 4 ...and out of which he is winner in 10,40 ( winner on bid prod_id ) ..WHY ONLY 10,40 and not 30 ...bcz user_id =4 has bid on prd=30 with amt =100 and user_id =2 with amt=100 ..but first bid was made by user=4 on prd=30 hence he is winner for prd=30 ( for same amt )
Tried below query for by prd_id but it giving me some wrong result.
SELECT `prd_id`, `user_id` , count('prd_id') as cont , max(`amnt`) as highestamt,disc
FROM `proddtails`
group by `prd_id` order by `prd_id`
above query result as below : ( user_id,disc not coming proper )
prd_id | user_id | cont | highestamt | disc
10 | 2 | 2 | 300 | 11
20 | 2 | 2 | 100 | 11
30 | 2 | 1 | 100 | 11
40 | 2 | 1 | 600 | 11
For second by user_id I am not getting what will be query.
Thanks
UPDATE :
THANKS FOR HARSHIL : http://www.sqlfiddle.com/#!9/5325a6/5/1
but after some more entry i found this bug : http://www.sqlfiddle.com/#!9/e04063/1 for second : for user_id but works well for prd_id (first query )
user_id cont bid_on_prd_id winner_on_bid_prod_id
1 1 10 (null)
2 4 10,20,40,30 10,40,30
3 1 20 20
4 1 30 30
but i want as below :
without null user_id
user_id cont bid_on_prd_id winner_on_bid_prod_id
2 4 10,20,30,40 10,40
3 1 20 20
4 1 30 30
with null user_id ( but in my wamp server i don't see null in winner_on_bid_prd_id for user_id =1 , i get value 10 instead of null )
user_id cont bid_on_prd_id winner_on_bid_prod_id
1 1 10 (null)
2 4 10,20,30,40 10,40
3 1 20 20
4 1 30 30

For prd_id:
select t1.prd_id,t1.user_id,
(select count(*) from tablename where prd_id = t1.prd_id)as cont,
t1.amnt as highststatment,
t1.dis as disc
from tablename t1
where (t1.prd_id,t1.amnt) in
(select prd_id, max(amnt) from tablename group by prd_id)
group by t1.prd_id;
For usr_id:
select t1.user_id,
count(*) as cont,
Group_concat(t1.prd_id separator ',') as bid_on_prd_id,
(select Group_concat(distinct t2.prd_id separator ',')
from tablename t2
where t2.user_id = t1.user_id
and (t2.id) in
(select min(id) from tablename
where (prd_id,amnt) in
(select prd_id,max(amnt) from tablename group by prd_id)
group by prd_id
)
) as winner_on_bid_prod_id
from tablename t1
group by t1.user_id
having winner_on_bid_prod_id IS NOT NULL;
Click here for UPDATED DEMO

Related

sql ranking with custom ties

Hello can you help me get the rank with custom ties?
i have a table of Scores stores all the scores given by the judges.
+----+----------+-------------+--------+
| Id | judge_id |performer_id | score |
+----+----------+-------------+--------+
| 1 | 1 | 1 | 98 |
| 2 | 1 | 2 | 98 |
| 3 | 1 | 3 | 94 |
| 4 | 1 | 4 | 96 |
| 5 | 2 | 1 | 93 |
| 6 | 2 | 2 | 80 |
+----+----------+-------------+--------+
heres what the code i have searched.
SELECT
id
, judge_id
, performer_id
, score
, FIND_IN_SET(
score
, (SELECT
GROUP_CONCAT(DISTINCT score ORDER BY score DESC)
FROM
scores
WHERE
judge_id = 1
)
) AS rank
FROM
scores
WHERE
judge_id = 1
ORDER BY rank ASC
and the output of this is:
+----+----------+-------------+--------+------+
| Id | judge_id |performer_id | score | rank |
+----+----------+-------------+--------+------+
| 1 | 1 | 1 | 98 | 1 |
| 2 | 1 | 2 | 98 | 1 |
| 3 | 1 | 4 | 96 | 3 |
| 4 | 1 | 3 | 94 | 4 |
+----+----------+-------------+--------+------+
it is working but the output is not what i want.
i want to get the ranking and ties like this.
+----+----------+-------------+--------+------+
| Id | judge_id |performer_id | score | rank |
+----+----------+-------------+--------+------+
| 1 | 1 | 1 | 98 | 1.5 |
| 2 | 1 | 2 | 98 | 1.5 |
| 3 | 1 | 4 | 96 | 3 |
| 4 | 1 | 3 | 94 | 4 |
+----+----------+-------------+--------+------+
where get all the rank of the tie then divide it by how many performer ties in the rank.
ex.
performer 1 score 98 rank 1
performer 2 score 98 rank 1
suppose that performer 2 should get rank 2
i want to compute it like
1+2 = 3 then divide it by 2 since 2 performers are tie in rank 1
1=2 = 3 / 2
answer is 1.5
im sorry for my english
but please can any one help me? im stuck at this problem.
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(performer_id SERIAL PRIMARY KEY
,score INT NOT NULL
);
INSERT INTO my_table VALUES
(1,98),
(2,98),
(3,94),
(4,96);
SELECT x.*
, y.rank
FROM my_table x
JOIN
( SELECT score
, SUM(i)/COUNT(*) rank
FROM
( SELECT score
, #i:=#i+1 i
FROM my_table x
ORDER
BY score DESC
, performer_id
) a
JOIN
( SELECT #i:=0 ) vars
GROUP
BY score
) y
ON y.score = x.score;
+--------------+-------+--------+
| performer_id | score | rank |
+--------------+-------+--------+
| 1 | 98 | 1.5000 |
| 2 | 98 | 1.5000 |
| 3 | 94 | 4.0000 |
| 4 | 96 | 3.0000 |
+--------------+-------+--------+
Note: For newer versions of MySQL, you would use Windowing functions/CTE (I'm not really sure of the correct terminology). I've written this for older versions, although MySQL can have issues when initializing variables this way. If that's a problem, here's another (slightly 'hackier' - and theoretically incorrect, but practically fine) way of initialising the variable...
SELECT x.*
, y.rank
FROM my_table x
JOIN
( SELECT score
, SUM(i)/COUNT(*) rank
FROM
( SELECT score
, #j:=#j+1 i
FROM my_table x
JOIN ( SELECT #j:=0 ) vars
ORDER
BY score DESC
, performer_id
) a
GROUP
BY score
) y
ON y.score = x.score;
+--------------+-------+------+
| performer_id | score | rank |
+--------------+-------+------+
| 1 | 98 | 1.5 |
| 2 | 98 | 1.5 |
| 3 | 94 | 4 |
| 4 | 96 | 3 |
+--------------+-------+------+

How to fetch data from table as per column value using PHP and MySQL

I need to filter value from table as per column value using PHP and MySQL. Here is my data:
db_images:
image_id member_id subcat_id from_day to_day
1 220 56 1 3
2 220 56 1 3
3 220 56 1 1
4 120 22 1 5
5 120 22 2 4
Here is my query:
$qry=mysqli_query($connect,"select * from db_iamges group by member_id,subcat_id order by image_id desc");
Using my query I am getting a record like below:
image_id member_id subcat_id from_day to_day
3 220 56 1 1
I need the to_day should always be higher value. If same member_id and subcat_id is present the the to_day will be always higher value and the from_day will be always smaller value. The expected output should like below.
image_id member_id subcat_id from_day to_day
1 220 56 1 3
4 120 22 1 5
It seems you have syntax problems, because if you copy-paste, you put "db_iamges". I made a table:
mysql> select * from prueba1;
+----------+-----------+-----------+----------+--------+
| image_id | member_id | subcat_id | from_day | to_day |
+----------+-----------+-----------+----------+--------+
| 1 | 220 | 56 | 1 | 3 |
| 2 | 220 | 56 | 1 | 3 |
| 3 | 220 | 56 | 1 | 1 |
| 4 | 120 | 22 | 1 | 5 |
| 5 | 120 | 22 | 2 | 4 |
| 6 | 120 | 22 | 2 | 9 |
| 7 | 120 | 22 | 2 | 2 |
+----------+-----------+-----------+----------+--------+
7 rows in set (0.00 sec)
And:
mysql> select image_id, member_id, subcat_id, min(from_day), max(to_day) from prueba1 group by member_id, subcat_id order by image_id asc;
+----------+-----------+-----------+----------+-------------+
| image_id | member_id | subcat_id | from_day | max(to_day) |
+----------+-----------+-----------+----------+-------------+
| 1 | 220 | 56 | 1 | 3 |
| 4 | 120 | 22 | 1 | 9 |
+----------+-----------+-----------+----------+-------------+
2 rows in set (0.00 sec)
It is working
EDIT: Updated, as I didn't understand your main problem.
Select
T.*
From db_images t
Inner join (
Select member_id, subcat_id, max(to_day) to_day
db_images group by member_id,subcat_id
) t2 on t.member_id = t2.member_id
And t.Subcat_id = t2.subcat_id
And t.to_day = t2.to_day;
use max(column name) to get higher value .
select image_id, member_id,subcat_id,from_day, max(to_day) as to_day from from db_iamges group by member_id,subcat_id order by image_id desc
try this
select t1.* from db_images t1 inner join(select max(member_id) as
mid,max(subcat_id) as cid,min(from_day) as fdy from db_images group
by member_id) t2 on t1.member_id = t2.mid and t2.cid = t1.subcat_id
and t2.fdy = t1.from_day group by member_id order by image_id asc;
check here

how to fetch sum every row mysql

Hy I have 2 table
1.application
id | name | status
====================
1 | morvick | complete
2 | siti | prosess
3 | boby | complete`
2.application_test
id | application_id | test_id | result
======================================
1 | 1 | 1 | 70
2 | 1 | 2 | 80
3 | 1 | 3 | 90
4 | 2 | 1 | 60
5 | 2 | 2 | 80
6 | 2 | 3 | 70
7 | 3 | 1 | 90
8 | 3 | 2 | 70
9 | 3 | 3 | 60
10| 3 | 4 | 80
my Question is :
==================
1. how I can to get sum(result) on each test_id where status complete
2. how I can to get sum(result) on each test_id where status prosess
for example to be like this :
test_id | SUM(result = complete) | SUM(result = proses) |
1 | 90 | 50
2 | 80 | 40
3 | 90 | 60
4 | 80 | 70
Try below query-
SELECT test_id,
SUM(IF(app.status='complete',apt.result,0)) AS complete_sum,
SUM(IF(app.status='process',apt.result,0)) AS process_sum
FROM application_test AS apt
JOIN application AS app ON app.id=apt.application_id
GROUP BY apt.test_id
You can try two query to get sum of result
SELECT test_id , SUM (result)
FROM application a
JOIN application_test t
ON t.test_id = a.id
WHERE a.status = 'complete'
GROUP BY test_id
SELECT test_id , SUM (result)
FROM application a
JOIN application_test t
ON t.test_id = a.id
WHERE a.status = 'prosess'
GROUP BY test_id
if you want in one query
SELECT test_id,
SUM(IF(a.status='complete',result,0)) Completed ,
SUM(IF(a.status='process',result,0)) Process
FROM application a
JOIN application_test t
ON a.id=t.application_id
GROUP BY t.test_id

Optimize MySQL query to find rank of a user for differnet tests in single query

I am using the query to find the rank of a user in a given test id, and this gives me rank for just one test at a time and I have to use foreach to get the test rank of all the test.
SELECT * , t.UserRank
FROM (
SELECT * , (
#rownum := #rownum +1
)UserRank
FROM User_Date_Table, (
SELECT #rownum :=0
)t
WHERE my_test_id = '$test_id'
ORDER BY test_score DESC
)t
WHERE user_id = '$my_user_id'
Can a query be generated which can give me user rank for all the test taken by user in single query as this will reduced the db hitting multiple times.
I have to find the all the ranks of user with Test_Type_Id = $my_test_type_id(say), joining a.id with b.my_test_id for a user with user_id = $my_user_id(say)
TABLE STRUCTURE
My_Test_Table (a)
id | name | Test_Type_Id
----------------------------------------------
1 | name_1 | 1
2 | name_2 | 1
3 | name_3 | 2
4 | name_4 | 1
5 | name_5 | 1
6 | name_6 | 2
7 | name_7 | 1
8 | name_8 | 2
9 | name_9 | 1
User_Date_Table (b)
id | my_test_id | user_id | test_score
---------------------------------------------------------
1 | 1 | 32 | 34
2 | 1 | 2 | 345
3 | 2 | 4 | 654
4 | 1 | 76 | 87
5 | 3 | 23 | 453
6 | 2 | 5 | 45
7 | 1 | 43 | 22
8 | 2 | 7 | 987
9 | 2 | 32 | 45
10 | 1 | 1 | 12
11 | 1 | 9 | 35
12 | 3 | 67 | 765
13 | 1 | 88 | 23
14 | 2 | 34 | 76
15 | 3 | 1 | 765
16 | 2 | 54 | 45
17 | 1 | 10 | 87
18 | 1 | 23 | 3
19 | 3 | 44 | 345
20 | 1 | 55 | 232
21 | 2 | 28 | 234
22 | 3 | 32 | 231
Simplest is probably to just remove the user variable for ranking and just do it using a subquery;
SELECT *, (SELECT COUNT(*)+1
FROM User_Date_Table b
WHERE a.my_test_id = b.my_test_id
AND a.test_score < b.test_score) userrank
FROM User_Date_Table a
WHERE user_id = '1';
An SQLfiddle to test with.
SELECT * , t.UserRank
FROM (
SELECT * , #rownum :=if(#user!=user_id,0, #rownum +1),#user:=user_id UserRank
FROM User_Date_Table , (SELECT #rownum :=0,#user :=-1) t
ORDER BY my_test_id ,test_score DESC
)t
WHERE user_id = '$my_user_id'
We introducean additional variable #user to reset #rownum on user_id change

display 0 to 23 hours table using php or mysql

I have a table in mysql that has time date and in military format ( 2014-01-22 16:10:02 )
caller_data
|ID | caller_id | call_time
| 1 | 123 | 2014-01-22 16:10:02
| 2 | 123 | 2014-01-22 16:30:02
| 3 | 123 | 2014-01-22 17:10:02
| 4 | 123 | 2014-01-22 18:05:45
on the range of their time like 16:10 and 16:30 . I group them using HOUR(), the result is 16. I will count it of how many times did the caller call on the range of that hour. so that would be 2.
My query:
SELECT caller_id,
HOUR(str_to_date(date_stamp, "%Y-%m-%d %H:%i:%s")) as hourly,
count(*) as total
from caller_data
group by hourly
order by hourly;
which the result should be:
caller_id | hourly | total
123 | 16 | 2
123 | 17 | 1
123 | 18 | 1
I want to display these 3 rows on a 0-23 . I've been trying to display this with php but it display 3 times when I created a for $i <= 23 ..
for($i=0;i<=23;$i++)
{
foreach ($rec as $row):
echo $row['hourly'];
echo $row['caller_id'];
echo $row['total'];
endforeach;
}
I dont know if it's possible to display this on mysql.. can someone show how to do it with php or mysql?
| hours | caller_id | total
| 0 | 123 | 0
| 1 | 123 | 0
| 2 | 123 | 0
| 3 | 123 | 0
| 4 | 123 | 0
| 5 | 123 | 0
| 6 | 123 | 0
| 7 | 123 | 0
| 8 | 123 | 0
| 9 | 123 | 0
| 10 | 123 | 0
| 11 | 123 | 0
| 12 | 123 | 0
| 13 | 123 | 0
| 14 | 123 | 0
| 15 | 123 | 0
| 16 | 123 | 2
| 17 | 123 | 1
| 18 | 123 | 1
| 19 | 123 | 0
| 20 | 123 | 0
| 21 | 123 | 0
| 22 | 123 | 0
| 23 | 123 | 0
You can do this in SQL with a left outer join. You just have to type in all the hours:
select caller_id, n.n as hourly, coalesce(total, 0) as total
from (select 1 as n union all select 2 union all select 3 union all select 4 union all
select 5 union all select 6 union all select 7 union all select 8 union all
select 9 union all select 10 union all select 11 union all select 12 union all
select 13 union all select 14 union all select 15 union all select 16 union all
select 17 union all select 18 union all select 19 union all select 20 union all
select 21 union all select 22 union all select 23 union all select 24
) n left outer join
(select caller_id, HOUR(str_to_date(date_stamp, "%Y-%m-%d %H:%i:%s")) as hourly,
count(*) as total
from caller_data
group by hourly
) rep
on n.n = rep.hourly
order by hourly;

Categories