table1 - customer_data
c_id (int)
name (varchar)
table2 - account_data
a_id (int)
c_id (int) -> use customer_data.c_id
plan_id (int)
table3 - game_data
g_id (int)
sort (int)
a_id (int) -> use account_data.a_id
game_name (var)
I using sub-query to select the game_data from account_data.
like that:
SELECT `a_id`,`c_id`,`plan_id`,
(SELECT `game_name` FROM `game_data` WHERE `a_id` = a.`a_id` ORDER BY `sort` ASC LIMIT 1) as main_game
FROM `accoubt_data` AS a WHERE `a_id` > 0 ORDER BY `id` DESC
this sql is work for select game_data from account_data
But I can't using it to select game_data from customer_data
How can I do something?
customer_data
+----------------------+
| c_id | name |
+----------------------+
| 1001 | Joe |
| 1002 | John |
| 1003 | David |
+----------------------+
account_data
+-------------------------------------+
| a_id | cid | plan_id |
+-------------------------------------+
| 6015 | 1002 | 34 |
| 6028 | 1003 | 1 |
| 6088 | 1001 | 9 |
+-------------------------------------+
game_data
+--------------------------------------+
| g_id | game_name | a_id |
+--------------------------------------+
| 8011 | GTA5 | 6015 |
| 8023 | WWE2016 | 6028 |
| 8088 | FIFA16 | 6088 |
| 8095 | FIFA17 | 6088 |
| 8086 | FIFA15 | 6088 |
+--------------------------------------+
this is base select
I need get this data from customer_data.c_id
+--------------------------------------+
| c_id | name | frist_game |
+--------------------------------------+
| 1001 | Joe | FIFA15 |
| 1002 | John | GTA5 |
| 1003 | David | WWE2016 |
+--------------------------------------+
c_id > a_id > g_id ORDER BY sort ASC
Try with join:
SELECT c.`c_id`,c.name,
(SELECT `game_name` FROM `game_data`
WHERE `a_id` = a.`a_id`
ORDER BY `sort` ASC LIMIT 1) as first_game
FROM `accoubt_data` a
JOIN customer_data c ON(a.c_id = c.c_id)
WHERE a.`a_id` > 0
ORDER BY a.`id` DESC
try this
SELECT cd.c_id,cd.name, first_game
FROM account_data ad
inner join game_data gd ON ad.a_id = gd.a_id order by gd.g_id,ad.a_id as games
inner join customer_data cd on games.c_id = cd.c_id order by cd.c_id
Hope this works.
Related
comment table
+------+----------+
| id | comment |
+------+----------+
| 1 | foo |
| 2 | bar |
| 3 | foobar |
+------+----------+
reply table
+------+----------+------------+
| id | reply |comment_id |
+------+----------+------------+
| 1 | nice lol | 1 |
| 2 | ok ok | 2 |
| 3 | hello | 1 |
| 4 | hello2 | 1 |
| 5 | hello1 | 1 |
+------+----------+------------+
SELECT
`comment`.`comment`,
`x`.`reply`
FROM `comment` LEFT JOIN
(SELECT GROUP_CONCAT(`reply`) as reply ,reply.commnt_id FROM `reply`
GROUP BY `reply`.`comment_id` ORDER BY `reply`.`id` LIMIT 0,1)x ON x.comment_id = comment.id
the result will be
+----------+-----------------+
| comment | reply |
+----------+-----------------+
| foo | nice lol,hello |
| bar | NULL |
| off | null |
+------+---------------------+
the question why the second comment have null but if i make limit 0,4 its will show it
Mysql does not support limits in group by clause. To achieve this type of feature we can hack group_concat as shown below:
SELECT
comment.comment,
x.replay
FROM comment LEFT JOIN
(SELECT
REPLACE(substring_index(group_concat(replay SEPARATOR '##'), '##', 2), '##', ',') as replay ,replay.commnt_id
FROM replay
GROUP BY replay.comment_id ORDER BY replay.id LIMIT 0,1)x
ON x.comment_id = comment.id
this is considering that your replies will not have '##' in them.
related posts:
GROUP_CONCAT with limit
Mysql group_concat limit rows in grouping
I have table as below , I want to take latest rating for the client
basically user whenever updates rating, count will be incremented and a entry will be made in table. Table goes as below
-----------------------------------------------------
|_id| name | client_id | user_id | rating | count |
-----------------------------------------------------
|1 | Four | 1 | 1 | 4 | 1 |
|2 | three | 1 | 1 | 3 | 2 |
|3 | two | 1 | 1 | 2 | 3 |
|4 | five | 1 | 1 | 5 | 4 |
|5 | two | 1 | 2 | 2 | 1 |
|6 | three | 1 | 2 | 3 | 2 |
|7 | two | 2 | 1 | 2 | 1 |
|8 | three | 2 | 1 | 3 | 2 |
-----------------------------------------------------
For rating of client_id 1 I want out put like
-----------------------------------------------------
|_id| name | client_id | user_id | rating | count |
-----------------------------------------------------
|4 | five | 1 | 1 | 5 | 4 |
|6 | three | 1 | 2 | 3 | 2 |
-----------------------------------------------------
so far I tried SELECT * FROM test
where client_id = 1 group by client_id order by count desc;
but not getting expected result, any help??
You can use left join on the same table as
select t1.* from test t1
left join test t2 on t1.user_id = t2.user_id
and t1.client_id = t2.client_id
and t1._id < t2._id
where
t2._id is null
and t1.client_id = 1
order by t1.`count` desc;
Using un-correlated subquery you may do as
select t1.* from test t1
join (
select max(_id) as _id,
client_id,
user_id
from test
where client_id = 1
group by client_id,user_id
)t2
on t1._id = t2._id
and t1.client_id = t2.client_id
order by t1.`count` desc;
UPDATE : From the comment how to join another table into above , for this here is an example
mysql> select * from users ;
+------+------+
| _id | name |
+------+------+
| 1 | AAA |
| 2 | BBB |
+------+------+
2 rows in set (0.00 sec)
mysql> select * from test ;
+------+-------+-----------+---------+--------+-------+
| _id | name | client_id | user_id | rating | count |
+------+-------+-----------+---------+--------+-------+
| 1 | four | 1 | 1 | 4 | 1 |
| 2 | three | 1 | 1 | 3 | 2 |
| 3 | two | 1 | 1 | 2 | 3 |
| 4 | five | 1 | 1 | 5 | 4 |
| 5 | two | 1 | 2 | 2 | 1 |
| 6 | three | 1 | 2 | 3 | 2 |
| 7 | two | 2 | 1 | 2 | 1 |
| 8 | three | 2 | 1 | 3 | 2 |
+------+-------+-----------+---------+--------+-------+
select t1.*,u.name from test t1
join users u on u._id = t1.user_id
left join test t2 on t1.user_id = t2.user_id
and t1.client_id = t2.client_id
and t1._id < t2._id
where
t2._id is null
and t1.client_id = 1
order by t1.`count` desc;
Will give you
+------+-------+-----------+---------+--------+-------+------+
| _id | name | client_id | user_id | rating | count | name |
+------+-------+-----------+---------+--------+-------+------+
| 4 | five | 1 | 1 | 5 | 4 | AAA |
| 6 | three | 1 | 2 | 3 | 2 | BBB |
+------+-------+-----------+---------+--------+-------+------+
Note that the join to users table is inner join and this will require all the user to be preset in users table which are in test table
If some users are missing in the users table then use left join this will have null values for the data selected from users table.
You may try something like
select _id, name, client_id, user_id, rating, max(count)
from clients
group by client_id
Try it
SELECT * FROM test
where client_id = 1
group by user_id
order by count desc
I have the following user table (don't ask me why :) )
| id | cid | attr | text | rdate |
---------------------------------------
| 1 | 1 | name | joe | NULL |
| 2 | 1 | date | NULL | 10.05.2014 |
| 3 | 1 | stat | 2 | NULL |
----------------------------------------
| 4 | 2 | name | joe | NULL |
| 5 | 2 | date | NULL | 05.05.2014 |
| 6 | 2 | stat | 1 | NULL |
----------------------------------------
| 7 | 3 | name | joe | NULL |
| 8 | 3 | date | NULL | 03.05.2014 |
| 9 | 3 | stat | 2 | NULL |
As you can see every user's attribute (name, date, stat) is a row in the table.
Attributes with the same cid belong to the same user.
I would like to delete all the entries which refer to a user whose attribute date is before 08.05.2014 AND whose attribute stat is not 2. So after running this query the table will be:
| id | cid | attr | text | rdate |
---------------------------------------
| 1 | 1 | name | joe | NULL |
| 2 | 1 | date | NULL | 10.05.2014 |
| 3 | 1 | stat | 2 | NULL |
----------------------------------------
| 7 | 3 | name | joe | NULL |
| 8 | 3 | date | joe | 03.05.2014 |
| 9 | 3 | stat | 2 | NULL |
Is it possible? Is this a inner join on the same table?
Group by the cid and use the having clause to run group functions to check out your requirements in every single group
delete from your_table
where cid in
(
select * from
(
select cid
from your_table
group by cid
having sum(attr = 'date' and `date` < '2014-05-08') > 0
and sum(attr = 'stat' and `text` = 2) = 0
) tmp_tbl
)
In MySQL you can't delete from the same table you are selecting from. But you can trick MySQL with another subquery like in the example above.
You can do this with delete/join:
delete t
from table t join
(select cid
from table t
group by cid
having max(case when attr = 'date' and date < '2014-05-08') > 0 and
max(case when attr = 'stat' and text <> '2') > 0
) s
on t.cid = s.cid;
I would do a fairly simple JOIN in the delete statement:-
DELETE a
FROM some_table a
INNER JOIN some_table b
ON a.cid = b.cid
INNER JOIN some_table c
ON a.cid = c.cid
WHERE b.attr = 'date' AND b.date < '2014-05-08'
AND c.attr = 'stat' AND c.text != '2'
Join will do :
Delete from mytable where cid in (select cid from
(select t1.cid FROM mytable t1 INNER JOIN mytable t2 ON t1.cid = t2.cid
WHERE t1.attr = 'date' AND t1.rdate < '2014-05-08'
AND t2.attr = 'stat' AND t2.text != 2) as sq)
I have two tables like this
profile_answers
+---------+------------+
| id | class_name |
+---------+------------+
| 1 | Class 1 |
| 2 | Class 2 |
| 3 | Class 1 |
+---------+------------+
educations
+---------+--------------------+------------+
| id | profile_answers_id | sample |
+---------+--------------------+------------+
| 1 | 1 | 1234 |
| 2 | 1 | 2334 |
| 3 | 1 | 3434 |
+---------+------------+--------------------+
I ran the query,
select educations.profile_answer_id, GROUP_CONCAT(educations.sample) from educations
LEFT JOIN profile_answers ON educations.profile_answers_id = profile_answers.id
I got
+--------+--------------------+-------------+
| id | sample |
+---------+--------------------+------------+
| 1 | 1234,2334,3434 |
+---------+------------+--------------------+
I actually want,
+--------+--------------------+-------------+
| id | sample |
+---------+--------------------+------------+
| 1 | 1234,2334,3434 |
| 2 | NULL |
| 3 | NULL |
+---------+------------+--------------------+
SELECT id,IFNULL(samples,'NULL') sample FROM
(
SELECT
AA.id,
GROUP_CONCAT(DISTINCT BB.sample) samples
FROM
profile_answers AA LEFT JOIN educations BB
ON AA.id = BB.profile_answers_id
GROUP BY AA.id
) A;
Looks like you're missing your GROUP BY:
select profile_answers.id, GROUP_CONCAT(educations.sample)
from profile_answers
LEFT JOIN educations ON educations.profile_answers_id = profile_answers.id
GROUP BY profile_answers.id
I also altered your JOIN to make the profile_answers table your main table.
Good luck.
I want to get the customer info where customer id should be 2 and the log_id should be maximum value
i tried below query but it is fetching first record found.
What will be the simple query
mysql> select * from log_customer where customer_id =2 group by customer_id having max(log_id);
+--------+------------+-------------+---------------------+-----------+----------+
| log_id | visitor_id | customer_id | login_at | logout_at | store_id |
+--------+------------+-------------+---------------------+-----------+----------+
| 2 | 56 | 2 | 2010-02-19 19:34:45 | NULL | 1 |
+--------+------------+-------------+---------------------+-----------+----------+
1 row in set (0.00 sec)
mysql> select * from log_customer where customer_id =2 limit 5;
+--------+------------+-------------+---------------------+---------------------+----------+
| log_id | visitor_id | customer_id | login_at | logout_at | store_id |
+--------+------------+-------------+---------------------+---------------------+----------+
| 2 | 56 | 2 | 2010-02-19 19:34:45 | NULL | 1 |
| 3 | 114 | 2 | 2010-02-23 17:31:55 | NULL | 1 |
| 31 | 1854 | 2 | 2010-03-08 18:31:28 | 2010-03-08 18:56:49 | 1 |
| 32 | 1992 | 2 | 2010-03-09 01:12:43 | NULL | 1 |
| 33 | 2304 | 2 | 2010-03-09 14:42:39 | NULL | 1 |
+--------+------------+-------------+---------------------+---------------------+----------+
Please do not suggest order by log_id desc I don't want to get in this way
SELECT *
FROM log_customer
WHERE customer_id = 2
AND log_id = (Select Max(Log_id)
FROM log_Customer
WHERE customer_id = 2)
That should do the trick
Edit without the Where:
SELECT *
FROM log_customer
WHERE log_id = (Select Max(Log_id)
FROM log_Customer
WHERE customer_id = 2)
Maybe this way:
SELECT *
FROM Log_Customer
WHERE Customer_Id = 2
AND Log_Id = (SELECT Max(Log_Id)
FROM Log_Customer
WHERE Customer_Id = 2)
A sub-select usually isn't bad as far as the execution plan is concerned.
select * from log_customer
left join
(select max(log_id) as max_id from log_customer where customer_id=2)
as log_customer2
on log_customer.log_id=log_customer2.max_id
where log_customer.customer_id=2;
oh damn...
select * from log_customer where customer_id=2 order by log_id desc limit 1;