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.
Related
I want to return every p row, and have null values for u.id and u.first_name if they dont have ROLE_ADMIN. When I perform this query I get empty result. If I use left join instead of inner I get incorrect results. How to filter left join so that If nothing matches I still get returned p rows with null values for u.id and u.first_name?
Note: I added p.id = 13455 at the end just for test purposes.
select u.id, u.first_name, p.id
from sub p
left join oub oj on oj.id = p.sub_id
left join jhi_user u on u.oub_id= oj.id
inner join jhi_user_authority ua on ua.user_id = u.id where ua.authority_name = 'ROLE_ADMIN' and p.id = 13544;
use left join like below
select u.id, u.first_name, p.id
from sub p
left join oub oj on oj.id = p.sub_id
left join jhi_user u on u.oub_id= oj.id
left join
( select * from
jhi_user_authority where authority_name = 'ROLE_ADMIN'
) ua on ua.user_id = u.id
where p.id = 13544;
I think the logic you want is:
select
ua.user_id,
case when ua.user_id is not null then u.first_name end as first_name,
p.id
from sub p
left join oub oj
on oj.id = p.sub_id
left join jhi_user u
on u.oub_id= oj.id
left join jhi_user_authority ua
on ua.user_id = u.id
and ua. authority_name = 'ROLE_ADMIN'
and u.id is not null
So I solved it like this:
select u.id, u.first_name, p.id
from sub p
left join oub oj on oj.id = p.sub_id
left join jhi_user u on u.id =
(select ru.id from jhi_user ru inner join jhi_user_authority rua on rua.user_id = ru.id and rua.authority_name = 'ROLE_ADMIN' where ru.oub_id= oj.id)
where p.id = 18774;
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.
I have the following query in which joins a couple of tables. One of those tables is profile_img. This table houses profile images for users who have uploaded them, otherwise they are given profile_images/default.jpg and the user is not in the profile_img table, so I need a case of sorts to check if they aren't in that table and then to set their profile image as the default.
Here is my query.
SELECT f.*, u.*, p.*
FROM friends f
LEFT JOIN
profile_img p
ON p.user_id = f.friend_one
JOIN
users u
ON u.id = f.friend_one
WHERE f.friend_two = ? AND f.status = ? AND
p.id = (select max(p2.id) from profile_img p2 where p2.user_id = p.user_id)
I have tried ,coalesce(p.img, 'profile_images/default.jpg') as img to try and get the result, but it did not help.
In another query:
(case when p.img <> '' then p.img
else 'profile_images/default.jpg'
end) as img
I am just not sure how to get it to work in this case and it does not work for this.
#marekful is correct in the use of ifnull() but there is one other fix thats needed.
In your where clause you are referencing p.id =. Since p will be null when there are no profile_img rows for that user, the whole row will be excluded from the results due to the compare to null.
This query takes into account the null p.id fields and includes them anyway by allowing p.id when its null. Now p.image_url will be null and the ifnull() method will respond with 'default.png' for those rows.
SELECT f.*, u.*, p.*, IFNULL(p.image_url, 'default.png') AS profile_pic
FROM friends f
LEFT JOIN
profile_img p
ON p.user_id = f.friend_one
JOIN
users u
ON u.id = f.friend_one
WHERE
f.friend_two = ?
AND f.status = ?
AND ( p.id is null or p.id = (select max(p2.id) from profile_img p2 where p2.user_id = p.user_id) )
You may also be able to do this without the OR clause by adding the subquery to the ON predicate. The subquery is then resolved before the join.
SELECT f.*, u.*, p.*, IFNULL(p.image_url, 'default.png') AS profile_pic
FROM friends f
JOIN
users u
ON u.id = f.friend_one
LEFT JOIN
profile_img p
ON p.user_id = f.friend_one and p.id = (select max(p2.id) from profile_img p2 where p2.user_id = p.user_id)
WHERE
f.friend_two = ?
AND f.status = ?
I'm not sure which one has better performance. You'll have to try that out for yourself.
You can select a field whose value will be set conditionally, e.g. using IFNULL()
SELECT f.*, u.*, p.*, IFNULL(p.image_url, 'default.png') AS profile_pic
FROM friends f
LEFT JOIN
profile_img p
ON p.user_id = f.friend_one
JOIN
users u
ON u.id = f.friend_one
WHERE f.friend_two = ? AND f.status = ? AND
p.id = (select max(p2.id) from profile_img p2 where p2.user_id = p.user_id)
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
I've 3 tables to query. I make a select on the first one, depending on the two others. I must have only distinct id from the 1st table, but my query is returning some duplicates... http://sqlfiddle.com/#!2/3e3d6/1
My query:
SELECT p.*
FROM posts p, blogs_subscribed s
WHERE (p.user_id = s.user_id OR p.user_id = 1)
AND p.id NOT IN (
SELECT post_id
FROM posts_unsubscribed u
WHERE u.post_id = p.id
AND u.user_id = p.user_id);
SELECT p.*
FROM posts p, blogs_subscribed s
WHERE (p.user_id = s.user_id OR p.user_id = 1)
AND NOT EXISTS(
SELECT null
FROM posts_unsubscribed u
WHERE u.post_id = p.id
AND u.user_id = p.user_id);
Any idea please?
not entirely sure I understand what you are looking for, but I think this is what you want...
SELECT p.*
FROM posts p, blogs_subscribed s
WHERE (p.user_id = s.user_id OR p.user_id = 1)
AND p.id NOT IN (
SELECT post_id
FROM posts_unsubscribed u
WHERE u.post_id = p.id
AND u.user_id = p.user_id)
GROUP BY p.id;
SELECT p.*
FROM posts p, blogs_subscribed s
WHERE (p.user_id = s.user_id OR p.user_id = 1)
AND NOT EXISTS(
SELECT null
FROM posts_unsubscribed u
WHERE u.post_id = p.id
AND u.user_id = p.user_id)
GROUP BY p.id;