how do I change my complex mysql query into mysql view - mysql

I'm a nubie in mysql queries, and I would like to ask, whether if there's someone who can help me to solve my problem. I have this complex(for me) sql. and I want to change it into a view.
SELECT
username,
user_id,
sum(result_points) AS count_points,
count(result_points) AS activity_done,
(
(
SELECT count(*) FROM `activity` WHERE periode_id = ''
) +
(
SELECT
IFNULL(sum(acs.result_points), 0)
FROM
user_activity ua
WHERE
periode_id = ''
AND ua.user_id = user_activity.user_id
AND ua.result_points IS NOT NULL
)
) AS total
FROM
user_activity
LEFT JOIN users ON users.id = user_activity.user_id
WHERE
periode_id = ''
and user_id > 0
GROUP BY user_id
ORDER BY total DESC
is there a way, to take out the "where" statement,so that i still can change it to view?

If you query is correct, create view like
Create View data as
SELECT
username,
user_id,
sum(result_points) AS count_points,
count(result_points) AS activity_done,
(
(
SELECT count(*) FROM `activity` WHERE periode_id = ''
) +
(
SELECT
IFNULL(sum(acs.result_points), 0)
FROM
user_activity ua
WHERE
periode_id = ''
AND ua.user_id = user_activity.user_id
AND ua.result_points IS NOT NULL
)
) AS total
FROM
user_activity
LEFT JOIN users ON users.id = user_activity.user_id
WHERE
periode_id = ''
and user_id > 0
GROUP BY user_id
ORDER BY total DESC
Remove where clause from view and add where clause in view, like
select * from data where user_id > 0

Related

SqlAlchemy: how to select in another select like this?

SELECT users.id, users.name,
(
SELECT coalesce(sum(games.point), 0)
from games
where games.point_type = 1
AND games.service_id = '9'
and games.user_id = users.id
) as earned,
(
SELECT coalesce(sum(games.point), 0)
from games
where games.point_type = 0
AND games.service_id = '9'
and games.user_id = users.id
) as awaiting,
(
SELECT coalesce(sum(games.point), 0)
from games
where games.point_type in (0, 1)
AND games.service_id = '9'
and games.user_id = users.id
) as total
FROM users, games
WHERE users.id = games.user_id
AND games.service_id = '9'
AND users.deleted_at IS NULL
GROUP BY users.id, users.name
ORDER BY total DESC
Hi, I'm a new user for SqlAlchemy, and it's my raw sql with postgresql, is it possible to work with SqlAlchemy?
I've tried search with subquery, but it's like query after From query...

SUM with CASE Statement in mysql

I have following Mysql query
SELECT c.`id`
,c.`category_name`
,c.`category_type`
,c.bookmark_count
,f.category_id cat_id
,f.unfollow_at
,(
CASE WHEN c.id = f.follower_category_id
THEN (
SELECT count(`user_bookmarks`.`id`)
FROM `user_bookmarks`
WHERE (`user_bookmarks`.`category_id` = cat_id)
AND ((`f`.`unfollow_at` > `user_bookmarks`.`created_at`) || (`f`.`unfollow_at` = '0000-00-00 00:00:00'))
)
ELSE 0 END
) counter
,c.id
,f.follower_category_id follow_id
,c.user_id
FROM categories c
LEFT JOIN following_follower_categories f ON f.follower_category_id = c.id
WHERE c.user_id = 26
ORDER BY `category_name` ASC
and here is output what i am getting after execuation
now i just want to count . here i have field id having value 172 against it i have counter 30,3, 2 and Bookmark_count is 4( i need to include only once)
and i am accepting output for id 172 is 30+3+2+4(bookmark_count only once).
I am not sure how to do this.
Can anybody help me out
Thanks a lot
The following may be the most inefficient query for that purpose, but I added a cover to your query in order to hint at grouping the results.
(I removed the second c.id, and my example may have errors since I couldn't try it.)
SELECT `id`,
`category_name`,
`category_type`,
max(`bookmark_count`),
`cat_id`,
`unfollow_at`,
sum(`counter`)+max(`bookmark_count`) counter,
follow_id`, `user_id`
FROM
(SELECT c.`id`
,c.`category_name`
,c.`category_type`
,c.bookmark_count
,f.category_id cat_id
,f.unfollow_at
,(
CASE WHEN c.id = f.follower_category_id
THEN (
SELECT count(`user_bookmarks`.`id`)
FROM `user_bookmarks`
WHERE (`user_bookmarks`.`category_id` = cat_id)
AND ((`f`.`unfollow_at` > `user_bookmarks`.`created_at`) || (`f`.`unfollow_at` = '0000-00-00 00:00:00'))
)
ELSE 0 END
) counter
,f.follower_category_id follow_id
,c.user_id
FROM categories c
LEFT JOIN following_follower_categories f ON f.follower_category_id = c.id
WHERE c.user_id = 26)
GROUP BY `id`, `category_name`, `category_type`, `cat_id`, `unfollow_at`, `follow_id`, `user_id`
ORDER BY `category_name` ASC

MySQL error: Operand should contain 1 column(s)

I have this MySQL Query (working)
First query:
SELECT id
FROM users
WHERE publisher_set = '1'
AND publisher_status = '1'
AND publisher_content != ''
AND publisher_amount != '0'
AND publisher_now < publisher_max
AND EXISTS (
SELECT *
FROM user_counter
WHERE users.id = user_counter.publisher_id
)
The MySQL query above is to find the user id from two table
Now I want to compared again using this second MySQL query (working)
Second query:
SELECT users.id, publisher_amount, publisher_now, publisher_max, counter
FROM users
INNER JOIN user_counter ON users.id = user_counter.publisher_id
WHERE no = 08123456789
AND counter < publisher_amount
But when I join all the query like this:
SELECT id
FROM users
WHERE publisher_set = '1'
AND publisher_status = '1'
AND publisher_content != ''
AND publisher_amount != '0'
AND publisher_now < publisher_max
AND EXISTS (
SELECT *
FROM user_counter
WHERE users.id = user_counter.publisher_id
)
AND (
SELECT users.id, publisher_amount, publisher_now, publisher_max, counter
FROM users
INNER JOIN user_counter ON users.id = user_counter.publisher_id
WHERE no =08123456789
AND counter < publisher_amount
)
I get this error:
Operand should contain 1 column(s)
Then, I try using 1 column, but the result is not what I wanted.
My question is How to join first and second query ? and produce no error.
I have tried google it and after many "try-and-error" this is the far I can get to make the query work.
I think you just miss an EXISTS on your second subquery. Anyway, if I understand your query correctly, I think you could write your query as this:
SELECT
u.id
FROM
users u inner join user_counter uc
on u.id=uc.publisher_id
and no=08123456789
and counter < publisher_amount
WHERE
u.publisher_set = '1'
AND u.publisher_status = '1'
AND u.publisher_content != ''
AND u.publisher_amount != '0'
AND u.publisher_now < publisher_max
You could change the first EXISTS clause to:
and users.id in (select user_counter.publisher_id from user_counter)
and use EXISTS on the final query.
You could also do this:
AND EXISTS (
SELECT user_counter.publisher_id
FROM user_counter
WHERE users.id = user_counter.publisher_id
PS: SQLFIDDLE doesn't work in my end for some reason. Else would have been happy to give you a demonstration ;)
SELECT id
FROM users
WHERE publisher_set = '1'
AND publisher_status = '1'
AND publisher_content != ''
AND publisher_amount != '0'
AND publisher_now < publisher_max
AND EXISTS (
select 1 from user_counter where users.id = user_counter.publisher_id
and no =08123456789
AND counter < publisher_amount
)
Assuming no and counter are on table user_counter. A bit hard to tell without a schema.

Set limit for MySQL query

I have query like this:
SELECT `all_messages`.`user_1`, `messages`.*, `users`.`username`
FROM `all_messages`
JOIN `messages` ON (`all_messages`.`user_2` = `messages`.`from_user`)
JOIN `users` ON (`all_messages`.`user_2` = `users`.`id`)
WHERE `all_messages`.`user_1` = '12'
ORDER BY `messages`.`sent` DESC LIMIT 2
Now this query does what I need but my problem is with this line
ON (`all_messages`.`user_2` = `messages`.`from_user`)
It selects all data from messages where the matches was found but I need only one newest record. I hope you guys get what I mean.
If you need one "newest record" you should have a date column or something, lets name it "CREATION_TIME", so you could do something like this
SELECT AM.user_1, M.*, U.username
FROM all_messages AM, messages M , users U
WHERE AM.user_1 = '12'
AND AM.user_2 = M.from_user
AND AM.user_2 = U.id
AND M.CREATION_TIME =
(
SELECT MAX(CREATION_TIME)
FROM messages
WHERE from_user= M.from_user
)
ORDER BY M.sent DESC LIMIT 2
Edit
SELECT AM.user_1, M.*, U.username
FROM all_messages AM, messages M, users U
WHERE AM.user_1 = '12'
AND AM.user_2 = M.from_user
AND AM.user_2 = U.id
AND M.sent =
(
SELECT MAX(sent)
FROM messages
WHERE from_user= M.from_user
)
ORDER BY M.sent DESC LIMIT 2
It should work

Mysql query optimization

HI im running socialengine3 and need optimization on the a custom Mutual friends query.
Its currently taking 15 seconds to execute
Friends table
friend_id
friend_user_id1
friend_user_id2
friend_status
friend_type
users
user_id
Edited
I have converted in into exists and still its now executing in 20 seconds.
below is the updated query.
SELECT friendlist.friend_user_id2, se_users.username, se_users.id, se_users.image, se_users.name, se_users.surname, count( * ) AS mutral_friends
FROM `se_friends` friendlist
INNER JOIN `users` se_users ON friendlist.friend_user_id2 = `se_users`.id
WHERE EXISTS (
SELECT se.friend_user_id2
FROM se_friends se
WHERE se.friend_user_id1 = '105012'
AND se.friend_status = '1'
AND se.friend_user_id2 = friendlist.friend_user_id1
) AND NOT EXISTS (
SELECT se1.friend_user_id2
FROM `se_friends` se1
WHERE se1.friend_user_id1 = '105012'
AND friendlist.friend_user_id2 = se1.friend_user_id2
)
AND NOT (
friendlist.friend_user_id2 = '105012'
)
AND friendlist.friend_status = '1'
GROUP BY friendlist.friend_user_id2, se_users.username, se_users.id, se_users.image, se_users.name, se_users.surname
ORDER BY mutral_friends DESC
LIMIT 0 , 20
Orignal query
SELECT DISTINCT `se_friends`.friend_user_id2, se_users.username, se_users.id, se_users.image, se_users.name, se_users.surname, count(*) as mutral_friends
FROM `se_friends`
INNER JOIN `users` se_users` ON `se_friends`.friend_user_id2=`se_users`.id
WHERE
(se_friends.friend_user_id1 <> '30355' or se_friends.friend_user_id2 <> '30355') AND
se_friends.friend_user_id1 IN
(SELECT se_friends.friend_user_id2
FROM `se_friends`
WHERE se_friends.friend_user_id1='".$user_id."' AND se_friends.friend_status='1')
AND `se_friends`.friend_user_id2 NOT IN
(SELECT se_friends.friend_user_id2
FROM `se_friends`
WHERE se_friends.friend_user_id1='".$user_id."'
)
AND NOT(se_friends.friend_user_id2='".$user_id."') AND se_friends.friend_status='1'
GROUP BY `se_friends`.friend_user_id2, se_users.username, se_users.id, se_users.image, se_users.name, se_users.surname
ORDER BY mutral_friends DESC
LIMIT 0, 20
IN is very expensive operation.
try to replace it with EXISTS. eg
select * from table where user_id in (select user_id from users where active='A')
and
select * from table t where exists (select user_id from users u where t.user_id = u.user_id and u.active='A')
if it won't be helpful, it's better to look at execution plan