I have this arrangement:
I want to retrieve all the posts shared by followeds, bearing in mind those shared posts doesnt belong to another followeds or the main follower.
TABLE USERS
id_user | name
15 Joe
16 Dan
17 Tom
TABLE COMMUNITY
id_follower | followed
15 16
15 17
TABLE POSTS
id_post | id_user | post
1 15 hi1
2 16 hi2
3 15 hi3
4 17 hi4
5 15 hi5
6 16 hi6
7 17 hi7
8 18 hi8
9 14 hi9
I'm adding up a new table "shares".
TABLE SHARES
id_sharer | id_post
16 4
14 8
17 8
16 9
EXPECTED OUTPUT POSTS
17 8 hi7 (shared by Tom)
16 9 hi6 (shared by Dan)
How shouldit be the sql query to get this new arrangement?
I was thinking adding a line LEFT JOIN shares l ON l.id_sharer=p.id_user
SELECT p.*,
FROM posts p
LEFT JOIN users u ON u.id_user=c.id_followed
LEFT JOIN shares l ON l.id_sharer=c.id_followed
LEFT JOIN community c ON c.id_follower=p.id_user
WHERE p.id_user=15
ORDER BY p.date_post DESC
*Tested but not retrieve as expected
Here is a first crack at this for you:
SELECT p.id_post, p.id_user, p.post, IF(l.date_like IS NOT NULL, l.date_like, p.date_post) AS date, l.id_liker
FROM posts p
LEFT JOIN likes l ON l.id_post = p.id_post
LEFT JOIN users u ON u.id_user = l.id_liker
ORDER BY l.date_like DESC
GROUP BY p.id_post
As a quick walk through of how I am approaching the problem, first I am LEFT JOINing the likes and ordering them in descending order, just as you did. Then I am grouping on the post id in order to ensure I only get one line per post. Then in the selector I am checking to see if the like date is null and substituting in the date of the post instead of the most recent like if there are no likes.
UPDATE
This should add the logic to ensure that only the likes of followers will count. Since one probably cannot follow themselves this should also keep one's own likes from affecting position.
SELECT p.id_post, p.id_user, p.post, IF(l.date_like IS NOT NULL, l.date_like, p.date_post) AS date, l.id_liker
FROM posts p
LEFT JOIN likes l ON l.id_post = p.id_post
LEFT JOIN users u ON u.id_user = l.id_liker
LEFT JOIN community c ON l.id_liker = c.followed
WHERE c.id_follower = 15
ORDER BY l.date_like DESC, p.date_post DESC
GROUP BY p.id_post
I understand that 'TABLE POSTS'.'id_user' is the author of the post and matches to 'TABLE USERS'.'id_user' and that you want to see the Posts that have Entries in 'TABLE LIKES' first and then all the others.
So I suggest to the following JOIN and ORDER BY
select p.*, l.date_like, u.* from posts p
left join likes l on p.id_post=l.id_post
left join users u on l.id_liker=u.id_user
order by l.date_like desc, p.date_post desc
Related
I want to do a query that return the number of posts that the user wrote in total , and the number of posts that he wrote of each category
I'm using this query:
SELECT USERS.username , POST_USERS.post_id , POST_CATEGORIES.category_name
FROM USERS
INNER JOIN POST_USERS on USERS.id = POST_USERS.user_ident
INNER JOIN POST_CATEGORIES on POST_USERS.post_id = POST_CATEGORIES.post_id;
and the result is:
---------+-------------+----------------+---
|username| post_id | category_name |
---------+-------------+----------------+---
pepe 77 css
pepe 77 php
juan 77 css
juan 77 php
(a post can have multiple categories)
What I want to get is this:
---------+--------------+---------------+--------
|username| total_posts | css | php |
---------+--------------+---------------+--------
pepe 5 2 3
juan 3 1 2
You are on the right track. The tables are properly joined, now we need to pivot the dataset. Provided that you know in advance the categories list, you can do conditional aggregation:
select
u.username,
count(*) total_posts,
sum(c.category_name = 'css') css,
sum(c.category_name = 'php') php
from users u
inner join post_users pu on pu.user_ident = u.id
inner join post_categories pc on pc.post_id = pu.post_id
group by u.id, u.username
I'm having an issue with a query of mine and how it's being joined. I need to pull some data from multiple tables in regards to CSR agents and the number of dealers they are associated with.
As shown below, I need to return a number of daily contact records for each user as well as a number of dealers associated with that number. Eventually I need to use a formula made from these 1 values, but I can do that with no problem I'm just having an issue getting the two values appropriately.
Currently, I'm getting the same number for both count values, where they should be different.
The code:
SELECT
c.user AS UserID,
COUNT(*) AS NumberOfDailyContacts, -- number of records in contact_events for this user
COUNT(d.csr) AS NumberOfDealerContacts, -- number of dealers associated with this user
FROM contact_events c
JOIN users u
ON c.user = u.id
JOIN dealers d
ON c.dealer_num = d.dealer_num
LEFT JOIN attr_list al
ON d.csr = al.data
GROUP BY UserID;
The fiddle: http://sqlfiddle.com/#!9/bd375/1
Desired output:
12345 | 2 | 3
23456 | 2 | 6
34567 | 2 | 2
45678 | 2 | 2
56789 | 2 | 5
67890 | 2 | 2
78911 | 2 | 4
But currently the fiddle is giving me all 2's for both columns.
The table structure for these tables sucks but it's what I'm given currently. The problem is that the contact events table uses the user ID for the CSR, where the dealer table associates by the 'data' value on the attribute_list table. So I basically have to say:
If the user ID In the contact_events table matches the user_id for a given data field in attr_list, show dealers associated with that user.
Hopefully the fiddle makes this a little more clear but I'll answer any questions you may have.
Use a subquery that joins attr_list with dealers to get the number of dealers per user.
select
c.user as UserID,
count(*) as NumberOfDailyContacts,
al.NumberOfDealerContacts
From contact_events c
join users u
on c.user = u.id
join dealers d
on c.dealer_num = d.dealer_num
left join (
SELECT user_id, COUNT(*) AS NumberOfDealerContacts
FROM attr_list AS al
JOIN dealers AS d ON d.csr = al.data
GROUP BY user_id) AS al
ON al.user_id = c.user
GROUP BY UserID
fiddle
Your joins were out of order, which caused your counts to get messed up. Here's what it should be, no subqueries needed:
SELECT
u.id AS UserID
,COUNT(DISTINCT c.id) AS NumberOfDailyContacts
,COUNT(DISTINCT d.dealer_num) AS NumberOfDealerContacts
FROM users u
LEFT JOIN attr_list al ON u.id = al.user_id
LEFT JOIN dealers d ON d.csr = al.data
LEFT JOIN contact_events c ON c.user = u.id
GROUP BY u.id;
mysql SELECT query with left join is not producing the result I am expecting.
I hope someone can show me or point me to the right direction,
I am trying to build a query where I get all the users name from the "users" table and
fetch the sum of all the time they spent for a particular date from the master table. I've used the left join but I am not getting the result as expected.
SUM(m.time_spent) as sum_total_time
FROM master as m
LEFT OUTER JOIN users as u ON u.user_id = m.user_id
WHERE m.date_created >= '2016-05-09'
AND m.date_created <= '2016-05-13'
GROUP BY name
ORDER BY name
master table
master_id user_id time_spent date_created
1 1 40 2016-05-01
2 2 36 2016-05-02
3 3 56 2016-05-03
4 2 33 2016-05-03
5 1 32 2016-05-05
nth nth nth number nth date
users table
user_id first_name last_name
1 James Green
2 Robert Cox
3 Andy Roger
etc etc etc
I want the output result should look like this:
user_id Name sum_total_time
1 James Green 62
2 Robert Cox 69
3 Andy Roger 56
4 Brian Harper 0
5 Angel Lee 0
6 Andrew Martin 55
.....
.....
Nth Name Nth value
You have to select data directly from the master table, group by user and calculate the sum. Then you can join this result with the user table to get all the information about the user.
Could be date conversione issue ..
SUM(m.time_spent) as sum_total_time
FROM master as m
LEFT OUTER JOIN users as u ON u.user_id = m.user_id
WHERE m.date_created >=STR_TO_DATE( '2016-05-09', '%Y-%m-%d)
and/or you have also incomplete sql
SUM(m.time_spent) as sum_total_time
FROM master as m
LEFT OUTER JOIN users as u ON u.user_id = m.user_id
WHERE m.date_created >= '2016-05-09'
AND m.date_created // this condition don't match with nothing..
// could be you forgot a part
Update 1
If you want user totale then
select u.id, u.name, SUM(m.time_spent) as sum_total_time
FROM master as m
Inner JOIN users as u ON u.user_id = m.user_id
WHERE m.date_created >=STR_TO_DATE( '2016-05-09', '%Y-%m-%d)
AND m.date_created <= =STR_TO_DATE('2016-05-13'', '%Y-%m-%d)
Group by u.id
Here is my tables:
topics
topic_id name
1 "Help!"
2 "Hey!"
3 "What?"
posts
post_id topic date content
1 2 2016-05-01 "Hey there!"
2 1 2016-05-04 "How to use WIFI?"
3 1 2016-05-05 "I dont know"
4 1 2016-05-02 "What is WIFI?"
5 3 2016-05-06 "What what?"
6 2 2016-05-02 "Hello"
I have this code
SELECT * from topics
LEFT JOIN posts
ON posts.topic = topics.topic_id
I want to join the posts with last (most recent) record only, and sort the records from topics by posts.date,
but I don't how to.
Expected result:
topic_id post_id date ...
3 5 2016-05-06 ...
1 3 2016-05-05 ...
2 6 2016-05-02 ...
Please try this Query
SELECT * from topics LEFT JOIN posts ON posts.topic = topics.topic_id
Left join (Select posts.topics, Max(posts.date) as Date From posts Group by posts.topics) as postgroup
on posts.date = postgroup.date and posts.topic = postgroup.topics;
Let me assume that post_id defines the last record. You can do this in various ways. Here is a method using WHERE and a correlated subquery:
SELECT *
FROM topics t LEFT JOIN
posts p
ON p.topic = t.topic_id
WHERE p.post_id = (SELECT MAX(p2.post_id) FROM posts p2 WHERE p2.topic = p.topic)
ORDER BY p.post_date DESC;
for example i have two tables:
posts {id,user_id,date}
design{user_id, bg_color}
and i have a post id of 18 for example, i want to retrieve the design's table by the same user_id of that post(which is 18)
how can i query this?
sorry for this stupid, im confused ? :))
SELECT design.user_id, design.bg_color
FROM posts
JOIN design
ON posts.user_id = design.user_id
WHERE posts.id = 18
In other words, we first select from posts where id is 18;
then we join design rows on which the user_id equals the user_id of the posts row.
We retrieve the corresponding user_id and bg_color from the design table.
Note that if there are multiple rows with the same design.user_id, you will get multiple rows back - example:
posts.id | posts.user_id
1 5
3 2
18 9
design.user_id | design.bg_color
2 '#aaffcc'
5 'red'
5 'blue'
9 '#000000'
9 '#cafe00'
query result:
posts.id | posts.user_id | design.user_id | design.bg_color
18 9 9 '#000000'
18 9 9 '#cafe00'
SELECT design.*
FROM design
JOIN posts on posts.user_id = design.user_id
where posts.ID = 18
You mean this?:
SELECT design.*
FROM design
JOIN posts ON design.user_id = posts.user_id
WHERE posts.id = ?givenid
Keep in mind that this could, based on the information you've given us, be a many-to-one relation. Are you looking for a single record or multiple records from the design table?
SELECT `design`.* FROM `design`, `posts` WHERE `posts`.`user_id` = `design`.`user_id` AND `posts`.`id` = 18
select * from posts join
design on
posts.user_id=design.user_id
where posts.id=18
Your question is a little confusing, but I think this will do the trick:
SELECT * FROM `posts` LEFT JOIN `design` USING (`user_id`) WHERE `posts`.`id` = 18