I'm trying to create a favorite system for my website. I have a user table, job table and a favorites table. When a user adds a job to their favorites, their userId and that jobsId is saved to the favorites table. When the user wants to see their favorites I've been trying to select all the rows in the favorites table that have the same userId as the current user. I then need to select the jobId's from these rows and select all the rows in the job table that have a matching jobId.
I've been trying variations of this query but haven't had any luck.
$sqlQuery = "SELECT * FROM job WHERE id = favorites.jobId AND :userId = favorites.userId"
You want all records from the jobs table whose IDs are in the user's favorites. This translates to:
select * from jobs where id in
(
select jobid from favorites where userid = :userid
);
How about:
Select j.*
from job j
join favorites f on j.id = f.jobId
where :userId = f.userId
Related
I have a MYSQL query that I am having difficulties getting to do what I want.
I have a users table (userstbl) containing all my user records, and a listings table (listings) contains all listings posted by each user. I am trying to select the name and address of each user and provide a count of listings for each user which was listed between a certain date range, but only count adverts for unique category_id's which is working fine.
The issue is that I only want to count listings that have been published. I have another table which is identical to my listings table called "listings_log" and contains a record for every change made to every listing record. If one of the records in "listings_log" for the listing has a "listings_log.published=1" than the listing was published. Each record in the "listings_log" table has a "listing_id" which is the same as in the "listings" table.
This is the query I have now :
SELECT
userstbl.userid,
userstbl.fullname,
userstbl.fulladdress,
COUNT(DISTINCT(
CASE WHEN listings.ad_type = 1
AND DATE(listings.date_listed) BETWEEN '2018-01-01' AND '2018-04-01'
THEN listings.category_id
END )
) AS Listings_Count_2018,
DATE_FORMAT(userstbl.reg_date, "%d/%m/%Y") AS RegisteredDate
FROM
users
LEFT JOIN listings ON listings.userid = userstbl.user_id
GROUP BY userstbl.userid
This counts the number of unique listings records between the correct dates for each user.
But I somehow only need to count listings records, where there is a corresponding listings_log record for that listing with published set to "1". The "listings_log" table and "listings" table both have a common listing_id column, but the listings_log table can have multiple records for each listing showing every change to each listing.
So I want to also join on the listings_log.listing_id = listings.listing_id and at least one of the "listings_log" records for that "listing_id" has listings_log.published = "1".
As you did not provide sample tables and a minimal reproducible example, a lot of this is guesswork. I am assuming for each user you want the total number of listing records. I built up the SQL with subqueries that are meant to be read "from the inside out."
select u.userid, u.fullname, u.fulladdress, sq.count from usertbl u join (
select u.userid, sum(c.count) as count from usertbl u join (
select count(*) as count, l.userid, l.listing_id from listings l join (
select distinct listing_id from listings_log where listings_log.published = "1"
) ll on l.listing_id = ll.listing_id
and l.ad_type = 1
and date(l.date_listed) between '2018-01-01' and '2018-04-01'
group by l.userid, l.listing_id
) c on u.userid = c.userid
group by u.userid
) sq on u.userid = sq.userid
;
See DB Fiddle
I have following query
select * from user_profile
Now i want to add where condition check user status from other table (users)
select * from user_profile,users where users.status!=0
Please Do Not Recommend Join i following old join query
Thanks
If you don't want to use join, you have to use a subquery. I guess both tables have a column like userId:
select * from user_profile where userId in (select userId from users where status != 0)
try this using sub query
select * from user_profile where status!=(select status from users where id =? or status=?)
what you compare id or status in subquery
Assuming you have a relation column (say user_id or perhaps profile_id or something -- not sure until you share sample data as requested.) between the two tables, you can join the two table and filter the rows like this:
select *
from user_profile p
join users u on p.user_id = u.user_id
where u.status != 0;
If you want every column from both tables in your query, you can use:
SELECT * from user_profile, users WHERE user_profile.user_id = users.id AND users.status! = 0
Where I assumed you have some column(like user_id - user_profile
and id - users in my example) that links both tables together.
I have two tables user & user login history. I need to make a report of the times a particular user is logging into the system. The table contains millions of rows of data. So running a nested query to fetch number of logins of users is taking a lot of time.
I am trying to loop through all the users and update the logins column. How can I do this in one query?
The schema is like this:
users table:
id INT(10)
username VARCHAR(7)
logins INT(10)
user_logs table:
id INT(10)
userid INT(10)
login_date DATETIME(19)
http://sqlfiddle.com/#!9/dc4149
I'm running this query
UPDATE users u
SET u.logins = (SELECT COUNT(*)
FROM user_logs
WHERE userid = u.id)
LIMIT 1
This is not working.
Is there any way how I could loop through users & update their respective login count?
I tried doing this with PHP but as the tables are very large. Doing this 1 by 1 takes very time.
Can I do this via command line?
An update should take so long, especially if you have proper indexed on both tables.
Try this:
UPDATE users u
INNER JOIN(SELECT ul.userid,count(1) as cnt FROM user_logs ul GROUP BY ul.userid) u2
ON(u2.userid = u.id)
SET u.logins = u2.cnt
Then make sure you have the following indexes:
users - (id,logins)
user_logins - (userid)
If that doesn't help - try doing this in two steps , build a derived table with the sub query results, and update by it :
CREATE TABLE temp_for_update AS(
SELECT ul.userid,count(1) as cnt
FROM user_logs ul
GROUP BY ul.userid);
CREATE INDEX YourIndex
ON temp_for_update (userid,cnt);
UPDATE users u
INNER JOIN temp_for_update u2
ON(u2.userid = u.id)
SET u.logins = u2.cnt
This should defiantly be faster.
Try using update join like
UPDATE users a
JOIN (
SELECT userid, COUNT(*) as count_login
FROM user_logs
GROUP BY userid) b ON b.userid = a.id
SET a.logins = b.count_login;
I have a question regarding MySql statement. I have 2 tables, record and training. Training table contains list of all courses, and record table contains list of courses that the user have attend. Training table is below
Record table format:
I want to get list non attending courses of each user. For eg: From the above table structure, user 277 is attending 130,167,128 & 2. So the non attending courses of user 277 is 3,4,5,7,8,9,147,11,12.
How can i write sql statement for getting the above result? Please help
Its something like this
SELECT * FROM training t WHERE t.id NOT IN (select trainingId from record where UserId=277 && piId=1) && t.status=1 ORDER BY t.categoryId
select id from training where id not in ( select trainingid from record where userid = yourid)
Get a list of users, cross join that with the training courses and then LEFT OUTER JOIN that to the table of training courses done by users. Us the WHERE clause to check there wasn't a match to the last table.
Untested, but something like this:-
SELECT sub_user.UserId, t.id
FROM
(
SELECT DISTINCT UserId from record
) sub_user
CROSS JOIN Training t
LEFT OUTER JOIN Record r
ON sub_user.UserId = r.UserId
AND r.trainingId = t.id
WHERE r.id IS NULL
If you have a table of users (which you probably do) then you could eliminate the sub query and replace it with that table.
Here's one example, I have a Car, User, Member, and Dealer tables. At the moment I'm trying to get the name of a dealer who owns a car by matching their userids up
Select userid, name FROM `User` WHERE userid IN
(SELECT userid FROM 'Car' WHERE userid in
(SELECT userid FROM `Member` WHERE userid IN
(SELECT userid FROM `Dealer`)))
This does what I want but I can't help feel there's a better way of doing it? Currently the userid in Car is a FK of the userid in Dealer which is a FK of the userid in Member which is a FK of the userid in User which stores the name.
Can I go straight to getting all the userid's and names of dealers who's id is in the Car table, whilst making sure they're actually a Dealer?
Basically your schema is a downstream schema
Users -> Members -> Dealer -> Car
Good thing is you made all the possible keys that you need here.
So to selct anything in any table just go down stream from Users for example for the data you want
Select * from `USER` u
where
dealer.user_id = car.user_id and
member.user_id = dealer.user_id and
u.user_id = member.user_id
The reason i went upstream in matching records is because we want to make as few matching operations as possible. As you can see user table is supposed to contain the maximum records. So i match with car table and get all the user_id where there is a match in dealer. similarly i go from dealer to member and then to user. this means all the records of users will be matched with a lot fewer records that they would have been if i went from users to members to dealer to car.
But this is not fool proof solution. it will depend on your data. because it may be a case where one user may have multiple cars, then it would be better to go downstream.
Use JOIN instead of subqueries to fetch the data.
Try this:
SELECT U.userid, U.NAME
FROM `User` U
INNER JOIN Car C ON U.userid = C.userid
INNER JOIN Member M ON C.userid = M.userid
INNER JOIN Dealer D ON M.userid = D.userid;