SQL server join query to get all subjects - join

I have the three tables:
TBL_SUBJECT, TBL_SEMESTER and TBL_SUBJECT_SEMESTER_MAPPING
I am having subjectId with me say '1', I want to get All the subjects of the semester to which my subject belongs. i.e subject having Id '1'.
How is the query with joins in SQL server.

Your question is not as clear as it could be. Please post schemas to get a better answer.
Answers will be something like this:
SELECT
SEMESTER_NAME
FROM
TBL_SEMESTER
INNER JOIN
TBL_SUBJECT_SEMESTER_MAPPING ON TBL_SUBJECT_SEMESTER_MAPPING.SUBJECTID = TBL_SEMESTER.SUBJECTID
INNER JOIN
TBL_SUBJECT TBL ON TBL_SUBJECT.SUBJECTID = TBL_SUBJECT_SEMESTER_MAPPING.SUBJECTID
WHERE
SUBJECTNAME LIKE YOURSUBJECT

I have done it like this
SELECT * from tbl_subject S
INNER JOIN tbl_subject_semester_mapping SSP ON SSP.subId = S.subId
INNER JOIN tbl_semester SEM ON SEM.semId = SSP.semId
WHERE SEM.semId = (select semId from tbl_subject_semester_mapping TSSM where TSSM.subId = 1 )

Related

Fetch records from multiple tables by JOIN in rails 2

I have my records set up as follows
UserKycScanResults: id, user_kyc_scan_id, match_name <- belongs to UserKycScan
UserKycScan: id, user_id, created_at <- belongs to User
User: id, firstname, lastname
I'm trying to write a join so that I can find users' firstname who have a entry in the user_kyc_scans table and user_kyc_scan table entry date is yesterday along with their match_name from user_kyc_scan_results table if present.
I have tried the following
UserKycScanResult.joins("INNER JOIN user_kyc_scans ON user_kyc_scans.id = user_kyc_scan_results.user_kyc_scan_id
INNER JOIN users ON users.id = user_kyc_scans.user_id").where("users.name = '#{submitted_first_name}', user_kyc_scans.created_at = #{Date.yesterday} ")
But this approach doesn't work. Any help would be appreciated.
And joins and where clauses are not working on rails 2
Please give me any solution to sort this out
Thanks.
Your inner joins query are right but in rails 2 we have to pass joins and conditions these way:
UserKycScanResult.all(:joins => "INNER JOIN user_kyc_scans ON user_kyc_scans.id = user_kyc_scan_results.user_kyc_scan_id
INNER JOIN users ON users.id = user_kyc_scans.user_id",
:conditions => ["users.name = ? AND user_kyc_scans.created_at = ?", submitted_first_name, Date.yesterday])
Document for reference: ruby on rails guides
Happy Coding

PHP/MYSQL: Obtain two items from table in join using different criteria

I am doing a join between tables to get a user pic from a user table about someone who comments on an article. However, I need to get a separate picture from the user table for a different user, the person who wrote the article at the same time. (There is a strong reason to do this in one query, as it's actually only one part of a more complex request).
Can anyone suggest how I could get two user pics from the users table during the join? This code gives me the first user pic, the commenter's pic or upic. But how do I also get the second user pic?
commments
id|comment|articleid|userid
1|great article|1|2
article
id|article|userid
1|Restaurant Openings|1
users
id|pic
1|mary.png
2|joe.png
$sql = "SELECT c.comment,c.articleid,c.userid,u.id, u.pic as upic,a.id,
FROM `comments` c
LEFT JOIN `articles` a
ON c.articleid = a.id
LEFT JOIN `users` u
ON c.userid= u.id
WHERE c.id=1";
A separate query to get the author's pic for would be:
$sqlauthorpic = "SELECT u.pic,u.id from `users` u
WHERE u.id = 1";
Thanks for any suggestions.
Join users again this time with article table, since you are looking for a user that wrote the article:
SELECT c.comment,c.articleid,c.userid,u.id, u.pic as upic,a.id, w.pic as wpic
FROM `comments` c
LEFT JOIN `articles` a ON c.articleid = a.id
LEFT JOIN `users` u ON c.userid= u.id
JOIN `users` w ON w.id = a.userid
You can also get rid of LEFT joins because, i think there could be no comments with out an article (articleid) and no comment without userid.

how to write a join condition in Ruby on Rails?

what I'm trying to do is to write something like the next query:
SELECT *
FROM Customers c
LEFT JOIN CustomerAccounts ca
ON ca.CustomerID = c.CustomerID
AND c.State = 'NY'
Notice that I'm not using any WHERE clause, but I need to my JOIN have a condition. I cannot make it work in Ruby on Rails.
Can you help me out?
You can join the tables with LEFT JOIN. Just pass the join condition in joins and you will get the expected result
Customer.joins("LEFT JOIN CustomerAccounts
ON CustomerAccounts.CustomerID = Customers.CustomerID
AND Customers.State = 'NY'")
#=> SELECT * FROM Customers LEFT JOIN CustomerAccounts ON CustomerAccounts.CustomerID = Customers.CustomerID AND Customers.State = 'NY'
Note: just .joins() does INNER JOIN so you need to specify the join with condition
Your SQL code, translated to activerecord, would look as follows (using joins):
Customer.where(state: 'NY').joins(:customer_accounts)
The code assumes, you have the association set up:
class Customer
has_many :customer_accounts
end

Rails Postgres query to exclude any results that contain one of three records on join

This is a hard problem to describe but I have Rails query where I join another table and I want to exclude any results where the join table contain one of three conditions.
I have a Device model that relates to a CarUserRole model/record. In that CarUserRole record it will contain one of three :role - "owner", "monitor", "driver". I want to return any results where there is no related CarUserRole record where role: "owner". How would I do that?
This was my first attempt -
Device.joins(:car_user_roles).where('car_user_roles.role = ? OR car_user_roles.role = ? AND car_user_roles.role != ?', 'monitor', 'driver', 'owner')
Here is the sql -
"SELECT \"cars\".* FROM \"cars\" INNER JOIN \"car_user_roles\" ON \"car_user_roles\".\"car_id\" = \"cars\".\"id\" WHERE (car_user_roles.role = 'monitor' OR car_user_roles.role = 'driver' AND car_user_roles.role != 'owner')"
Update
I should mention that a device sometimes has multiple CarUserRole records. A device can have an "owner" and a "driver" CarUserRole. I should also note that they can only have one owner.
Anwser
I ended up going with #Reub's solution via our chat -
where(CarUserRole.where("car_user_roles.car_id = cars.id").where(role: 'owner').exists.not)
Since the car_user_roles table can have multiple records with the same car_id, an inner join can result in the join table having multiple rows for each row in the cars table. So, for a car that has 3 records in the car_user_roles table (monitor, owner and driver), there will be 3 records in the join table (each record having a different role). Your query will filter out the row where the role is owner, but it will match the other two, resulting in that car being returned as a result of your query even though it has a record with role as 'owner'.
Lets first try to form an sql query for the result that you want. We can then convert this into a Rails query.
SELECT * FROM cars WHERE NOT EXISTS (SELECT id FROM car_user_roles WHERE role='owner' AND car_id = cars.id);
The above is sufficient if you want devices which do not have any car_user_role with role as 'owner'. But this can also give you devices which have no corresponding record in car_user_roles. If you want to ensure that the device has at least one record in car_user_roles, you can add the following to the above query.
AND EXISTS (SELECT id FROM car_user_roles WHERE role IN ('monitor', 'driver') AND car_id = cars.id);
Now, we need to convert this into a Rails query.
Device.where(
CarUserRole.where("car_user_roles.car_id = cars.id").where(role: 'owner').exists.not
).where(
CarUserRole.where("car_user_roles.car_id = cars.id").where(role: ['monitor', 'driver']).exists
).all
You could also try the following if your Rails version supports exists?:
Device.joins(:car_user_roles).exists?(role: ['monitor', 'driver']).exists?(role: 'owner').not.select('cars.*').distinct
Select the distinct cars
SELECT DISTINCT (cars.*) FROM cars
Use a LEFT JOIN to pull in the car_user_roles
LEFT JOIN car_user_roles ON cars.id = car_user_roles.car_id
Select only the cars that DO NOT contain an 'owner' car_user_role
WHERE NOT EXISTS(SELECT NULL FROM car_user_roles WHERE cars.id = car_user_roles.car_id AND car_user_roles.role = 'owner')
Select only the cars that DO contain either a 'driver' or 'monitor' car_user_role
AND (car_user_roles.role IN ('driver','monitor'))
Put it all together:
SELECT DISTINCT (cars.*) FROM cars LEFT JOIN car_user_roles ON cars.id = car_user_roles.car_id WHERE NOT EXISTS(SELECT NULL FROM car_user_roles WHERE cars.id = car_user_roles.car_id AND car_user_roles.role = 'owner') AND (car_user_roles.role IN ('driver','monitor'));
Edit:
Execute the query directly from Rails and return only the found object IDs
ActiveRecord::Base.connection.execute(sql).collect { |x| x['id'] }

Where clause filtering by "ANY" - What does this means?

I'm trying to understand why I don't receive any records on a ruby on rails app using postgresql. This is the SQL query that is being executed:
SELECT g.program_id, g.title,
COALESCE(COUNT(pr), 0) AS ac, g.default
FROM groups AS g
LEFT OUTER JOIN memberships AS m ON m.group_id = g.id
LEFT OUTER JOIN progresses AS pr ON m.id = pr.participant_id
AND (pr.status = 'completed')
WHERE g.program_id = ANY(#1)
GROUP BY g.id
ORDER BY g.program_id, g.position, g.id
My question is: what does the ANY(#1) means?
Please have pacience, as I'm a ruby/rails/postgresql newbie.
Thanks!
Update: added some aditional code. Plese don't ident the query below as it is already idented above.
class StatsComponents::CompletedActivitiesPerGroupStats
include StatsComponent::Interface
GROUP_ACTIVITIES = <<-SQL
g.program_id, g.title, COALESCE(COUNT(pr), 0) AS ac, g.default
FROM groups AS g
LEFT OUTER JOIN memberships AS m ON m.group_id = g.id
LEFT OUTER JOIN progresses AS pr ON m.id = pr.participant_id
AND (pr.status = 'completed')
WHERE g.program_id = ANY(#1)
GROUP BY g.id
ORDER BY g.program_id, g.position, g.id
SQL
def generate
...
It selects records where g.program_id has a value existing in the array returned by #1 request, which they set as a query parameter (for example SELECT...) somewhere further in the program.
You can equally use SOME(#1) here.
By the way strictly speaking, this isn't a sql query. While there is no sql.execute or something like that, it's just a multiline string assignment.

Resources