I want to know how to complete this query correctly.
I wish to export a full list of votes from all ips used by an user.
My database have 3 tables storing the relatives data =>
votes = vote_site_id | vote_ip | vote_time
connexions_ip = adresse_ip | user_id | connexion_time
users = user_id | user_name | user_ip
So actually I have this query to have all connexions_ip from one user =>
SELECT c.adresse_ip, c.user_id, u.user_name
FROM connexions_ip c
LEFT JOIN users u ON u.user_id = c.user_id
WHERE u.user_id = '1'
And this query to have all votes from one user =>
SELECT v.vote_site_id, v.vote_ip, v.vote_time, u.user_name
FROM votes v
LEFT JOIN users u ON u.user_ip = v.vote_ip
WHERE user_id = '1'
I tried with subquery but I have this error "#1242 - Subquery returns more than 1 row"
SELECT v.vote_site_id, v.vote_ip, v.vote_time, u.user_name
FROM votes v
LEFT JOIN users u ON (
SELECT c.adresse_ip
FROM connexions_ip c
LEFT JOIN users u ON u.user_id = c.user_id
WHERE u.user_id = '1'
)
= v.vote_ip
WHERE user_id = '1'
Thanks for your help.
You can join all the table
SELECT c.adresse_ip, c.user_id, u.user_name
, v.vote_site_id, v.vote_ip, v.vote_time
FROM users u
LEFT JOIN connexions_ip c ON u.user_id = c.user_id
LEFT JOIN votes v ON u.user_ip = v.vote_ip
WHERE u.user_id = '1'
I choosed the table users as the base for FROM because is the only table with a condition.
try this:
select a.*,b.* from (SELECT c.adresse_ip, c.user_id, u.user_name
FROM connexions_ip c
LEFT JOIN users u ON u.user_id = c.user_id
WHERE u.user_id = '1')a left join (SELECT u.user_id,v.vote_site_id, v.vote_ip, v.vote_time, u.user_name
FROM votes v
LEFT JOIN users u ON u.user_ip = v.vote_ip
WHERE user_id = '1')b on a.user_id = b.user_id
Related
I want to display all users data, who User 'A' is following. And then further check if User 'B' is also following some users of User 'A'.
I managed to get al users data, who User 'A' is following. But don't understand how to query for the second condition.
Here is my Fiddle link with an example: https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=29a7d1e29f794a8f18a89fe45c06eaa9
You can try to let your User 'B' in a subquery then do OUTER JOIN
SELECT u.*,
IF(friend_id IS NULL,0,1) amIfollowing
FROM users u
LEFT JOIN (
Select friend_id
from friends
where user_id = 5
) f ON f.friend_id = u.id
WHERE u.id IN (SELECT f.friend_id
FROM friends f
WHERE f.user_id = 1)
ORDER BY u.id
sqlfiddle
If I understand correctly you can try to use only one subquery for friends and then use the condition aggregate function to get the result.
SELECT u.id,
u.image_width,
MAX(CASE WHEN f.user_id = 5 THEN 1 ELSE 0 END) amIfollowing
FROM users u
JOIN (
Select friend_id,user_id
from friends
where user_id IN (1,5)
) f ON f.friend_id = u.id
GROUP BY u.id,
u.image_width
ORDER BY u.id
You could use exists here to check if the corresponding IDs exist:
SELECT *,
case when exists (
select * from friends f
where f.friend_id = u.id and f.user_id = 5
) then 1 else 0 end amIfollowing
FROM users u
WHERE u.id IN (SELECT f.friend_id
FROM friends f
WHERE f.user_id = 1);
Example Fiddle
Looks like a JOIN will do, with distinct
SELECT distinct u.*, (f2.user_Id is not null) amIfollowing
FROM users u
JOIN friends f ON u.id = f.friend_id
LEFT JOIN friends f2 on f2.friend_id = f.friend_id and f2.user_id = 5
WHERE f.user_id = 1
ORDER BY u.id
I'm working on a project where I need to check if the user liked the post and then use COUNT() on it, if it gives 0 they haven't if it says 1 they have liked it
I tried using this query
SELECT P.id AS id
, U.username AS username
, P.body AS body
, P.timestamp AS timestamp
, COUNT(L.user_id) AS likes
, COUNT(LD.post_id) AS liked
FROM posts AS P
LEFT JOIN users AS U ON U.id = P.user_id
LEFT JOIN followers AS F ON F.user_id = 'user1'
LEFT JOIN likes AS L ON L.post_id = P.id
LEFT JOIN likes AS LD ON LD.post_id = P.id
AND LD.user_id = 'user1'
WHERE F.following_id = P.user_id
OR P.user_id = 'user1'
GROUP BY P.id
My entrys in my likes table are
UserId|PostId|timestamp
user1 |post1 |time
user2 |post1 |time
My problem is it keeps giving a 2 for the count of LD which shouldn't be possible
*Note: In my code I use :user through PDO I don't actually type the id like that
Edit:
$sql = "SELECT P.id AS id, P.user_id AS userid, U.username AS username, U.name AS name, U.verified AS verified, P.body AS body, P.data AS data, P.timestamp AS timestamp, P.type AS type, P.users AS users, COUNT(L.user_id) AS likes, COUNT(DISTINCT LD.post_id) AS liked FROM posts AS P LEFT JOIN users AS U ON U.id = P.user_id LEFT JOIN followers AS F ON F.user_id = :userid LEFT JOIN likes AS L ON L.post_id = P.id LEFT JOIN likes AS LD ON LD.post_id = P.id AND LD.user_id = :userid WHERE F.following_id = P.user_id OR P.user_id = :userid GROUP BY P.id";
$results = DB::query($sql, array(':userid' => $user_id));
I then loop through the results and format them into json
Can you try adding a DISTINCT keyword on the COUNT function for liked column?
COUNT(DISTINCT LD.post_id) AS liked
Most likely the joins are causing the likes table to be duplicated. Thus, we'll only count the unique posts (by post_id) using DISTINCT.
Imagine the following table structure:
tb.user tb.usergroups tb.group
id id id
name user_id name
group_id
A user can be in multiple groups through the usergroups table.
I want to search for a user by user name and group name. Speaking in examples: user "Bob" is in "GroupA" and in "GroupB". My query so far:
SELECT *
FROM user u
JOIN usergroups ug ON ug.user_id = u.id
JOIN group g ON ug.group_id = g.id
WHERE u.name = 'Bob' AND g.name != 'GroupA'
This isn't exactly what I want; my result still contains Bob, since he's in "GroupB", but I don't want the result to contain Bob at all.
How to do that?
Thanks
I understand you want to select all users named "Bob" that are not in group A but are in group B. This should do it :
SELECT b.*
FROM (SELECT * FROM user u
JOIN usergroups ug ON ug.user_id = u.id
JOIN group g ON ug.group_id = g.id
WHERE u.name = 'Bob' AND g.name = 'GroupB') b
LEFT JOIN (SELECT userid FROM user u
JOIN usergroups ug ON ug.user_id = u.id
JOIN group g ON ug.group_id = g.id
WHERE u.name = 'Bob' AND g.name = 'GroupA') a
ON a.userid=b.userid
WHERE a.userid is NULL
Check this query as i understand you are looking something like this:
SELECT * FROM user AS u
LEFT JOIN usergroups AS ug ON u.id = ug.user_id
LEFT JOIN groups AS gp ON gp.id = ug.group_id
WHERE u.name = 'Bob'
GROUP by ug.user_id
HAVING count(ug.group_id) = 1 AND gp.name !="GROUPA"
Is it possible to do something like this:
SELECT
p.*, u.*
FROM
posts AS p
IF(p.status = 1)
LEFT JOIN users AS u
ON u.id = p.user_id
ELSE
LEFT JOIN pusers AS u
ON u.id = p.user_id
WHERE p.id = 10 ;
Based on post status being true/false join users/pusers table
No, but you can do this:
SELECT p.*,
(case when p.status = 1 then u.col1 else pu.col1 end) as col1
FROM posts p LEFT JOIN
users u
ON u.id = p.user_id and p.status = 1 LEFT JOIN
pusers AS pu
ON pu.id = p.user_id and p.status <> 1
WHERE p.id = 10 ;
In other words, you can join both tables and use the values from the table, based on the condition.
We have following tables...
users
id, username password email
user_clubs
id, user_id, club_name
sales
id, club_id, amount, admin_fees, dnt
We are trying to get total sum of admin_fees as outstanding for user_id(for example 5), and we tried following...
SELECT u.id, count(c.id), SUM(s.admin_fees) as total_admin_fees
FROM users u
LEFT JOIN user_clubs c ON c.user_id = u.id
LEFT JOIN sales s ON s.club_id = c.id
WHERE u.id = 5
GROUP BY u.id;
Which is only returning results for first row, which is incorrect, Please help to resolve.
here is sql fiddle to test.
thanks
Try this one for user_id = 5 there are two club ids and with amount 2,5 so total should be 7
SELECT u.id, COUNT(c.id), SUM(s.admin_fees) AS total_admin_fees
FROM users u
LEFT JOIN user_clubs c ON c.user_id = u.id
LEFT JOIN sales s ON s.club_id = c.id
WHERE u.id = 5
GROUP BY s.club_id;
for all users you can do this
SELECT u.id, COUNT(c.id), SUM(s.admin_fees) AS total_admin_fees
FROM users u
LEFT JOIN user_clubs c ON c.user_id = u.id
LEFT JOIN sales s ON s.club_id = c.id
GROUP BY u.`id`;
Fiddle