How to join with three tables with multiple conditions? - join

I want to join three tables with multiple conditions. Below is table structure and expected result
users_id users_first_name
1 rocky
2 James
3 john
meeting_details_id meeting_title users_id meeting_lead close_meeting (NO)
1 newmeet 3 1 No
2 testmeet 2 2 No
Attended_meetings
project_meeting_attendeeid meeting_details_id users_id access_type (attendee)
1 1 2 attendee
Expected output:
Query should check if meeting is attended OR users is meeting lead
meeting_title creator meeting_lead close_meeting (NO)
newmeet john rocky No
testmeet james james No

Try this:
SELECT M.meeting_title,U1.users_first_name as creator,U2.users_first_name as meeting_lead,M.close_meeting
FROM MeetingTable M LEFT OUTER JOIN
Users U1 ON M.creator=U1.users_id LEFT OUTER JOIN
Users U2 ON M.meeting_lead=U2.users_id
Result:
MEETING_TITLE CREATOR MEETING_LEAD CLOSE_MEETING
newmeet john rocky No
testmeet James James No
See result in SQL Fiddle.

Related

Kusto join two tables based on latest available date

Is there a way to join two tables on Kusto, and join values based on latest available date from the second table?
Let's say we get distinct names from first table, and want to join values from the second table based on latest available dates.
I would also only keep matches from left column.
table1
names
-----
Alex
John
Mary
table2
name weight date
----- ------ ------
Alex. 160. 2023-01-20
Alex. 168. 2023-01-28
Mary. 120. 2022-08-28
Mary. 140. 2020-09-17
Sample code:
table1
|distinct names
|join kind=inner table2 on $left.names==$right.name
let table1 = datatable(names:string)
[
"Alex"
,"John"
,"Mary"
];
let table2 = datatable(name:string, weight:real ,["date"]:datetime)
[
"Alex" ,160 ,datetime(2023-01-20)
,"Alex" ,168 ,datetime(2023-01-28)
,"Mary" ,120 ,datetime(2022-08-28)
,"Mary" ,140 ,datetime(2020-09-17)
];
table1
| distinct names
| join kind=inner (table2 | summarize arg_max(['date'], *) by name) on $left.names==$right.name
names
name
date
weight
Mary
Mary
2022-08-28T00:00:00Z
120
Alex
Alex
2023-01-28T00:00:00Z
168
Fiddle

How to fix group in complex query in rails or do a join on two separate query results and then query again

I have been stuck with this problem for a while at work. The data given has been radically changed as I just need the general idea of how to approach the problem, and it would not be possible to provide the actual schema of the tables.
I have a table Users and and another table Membership. And each user has a one to many relationship with membership through the user_membership table. A mock up of the following table is shown below:
id
name
email
1
John
john#gmail.com
2
James
james#gmail.com
...
...
...
id
user_id
membership_id
1
2
1
2
1
2
3
1
3
4
1
4
5
1
5
...
...
...
id
created_at
1
31st Dec 2021
2
1st Jan 2022
3
2nd Jan 2022
4
3rd Jan 2022
5
4th Jan 2022
...
...
I have some level of rather complex querying that returns an ActiverecordRelation.
ie:
users = Users.select(....)
I then need to chain the above query with another query that allows each user with their latest membership_created_at date. Ie:
<User, id: 1, name: John ,email: john#gmail.com, latest_membership_created_at: 4th Jan 2022>
<User, id: 2, name: James ,email: james#gmail.com, latest_membership_created_at: 31st Dec 2021>
My approach:
users = users.joins(user_memberships: :membership).merge(User.all).group(:id).select('membership.*, MAX(membership.created_at) AS membership_created_at_raw')
I get an error:
Query 1 ERROR: ERROR: column "users.id" must appear in the GROUP BY clause or be used in an aggregate function...
Qn 1: Is there anyway I can fix this?
In another related note, is it also possible to do a join of the result of 2 queries? I am thinking perhaps I can do a group of user_membership table by user_id and join with the membership table. Something like
users_created_at = User.all.joins(user_memberships: :membership[).group(:id).select('user.id, MAX(memberships.created_at) AS membership_created_at_raw')
Qn 2: Can we then somehow do an innerjoin between users and users_created_at using rails?
Thank you!
You can do it like this:
User.select(
'DISTINCT ON (users.id) users.id, memberships.*'
).joins(
user_memberships: :membership
).order('users.id, memberships.created_at DESC')
Or raw SQL query
SELECT DISTINCT ON (users.id) users.id, memberships.*
FROM users
LEFT JOIN user_memberships ON user_memberships.user_id = users.id
LEFT JOIN memberships ON memberships.id = user_memberships.membership_id
ORDER BY users.id, memberships.created_at DESC

Many-to-many SELECT divided into multiple rows for some reason

I have two tables joined via third in a many-to-many relationship. To simplify:
Table A
ID-A (int)
Name (varchar)
Score (numeric)
Table B
ID-B (int)
Name (varchar)
Table AB
ID-AB (int)
A (foreign key ID-A)
B (foreign key ID-B)
What I want is to display the B-Name and a sum of the "Score" values of all the As belonging to the given B. However, the following code:
WITH "Data" AS(
SELECT "B."."Name" As "BName", "A"."Name", "Score"
FROM "AB"
LEFT OUTER JOIN "A" ON "AB"."A" = "A"."ID-A"
LEFT OUTER JOIN "B" ON "AB"."B" = "B"."ID-B")
SELECT "BName", SUM("Score") AS "Total"
FROM "Data"
GROUP BY "Name", "Score"
ORDER BY "Total" DESC
The results display several rows for every "BName" with the "score" divided into semingly random increments between these rows. For example, if the desired result for Johnny is 12 and for April it's 25, the query may shows something like:
Johnny | 7
Johnny | 3
Johnny | 2
April | 19
April | 5
April | 1
etc.
Even after trying to nest the query and doing another SELECT with SUM("Score"), the results are the same. I'm not sure what I'm doing wrong?
Remove Score from the GROUP BY clause:
SELECT BName, SUM(Score) AS Total
FROM Data
GROUP BY BName
ORDER BY Total DESC;
The purpose of your query is to summarize by name, so name alone should appear in the GROUP BY clause. By also including the score, you will get a record in the output for each unique name/score combination.
Okay, I figured out my problem. Indeed, I had to GROUP BY "Name" only, but Firebird I thought wasn't letting me do that. Turns out it was just a typo. Oops.

How to query table to get one row requiring two joins to two separate ID?

Oracle 11g
PERSON table contains both seller and buyer ID. How can I get buyer and seller into single result set? I can get results to list either the buyer or the seller but not both.
Person
=================
PersonID First Last
1 Joe Camel
2 Ronald McFly
3 Barbara Wawa
SalesDetail
=========================
TransID Amount SellerID CustomerID
98 500 1 2
99 700 3 1
Desired Result
===========================================
SellerID SellerLast BuyerID BuyerLast Amount
1 Camel 2 McFly 500
3 Wawa 1 Camel 700
Just join to the Person table twice
SELECT sd.sellerID,
seller.last sellerLast,
sd.buyerID,
buyer.last buyerLast,
sd.amount
FROM salesDetail sd
JOIN person seller ON (sd.sellerID = seller.personID)
JOIN person buyer ON (sd.buyerID = buyer.personID)
You may want outer joins if it is possible that either the buyer or the seller is unknown.
try this
select seller.sellerid,
seller.last,
buyer.buyerid,
buyer.last,
amount
from
person buyer
inner join salesdetail on buyer.personid = salesdetail.cutomerid
inner join person seller on salesdetail.sellerid = seller.personid
unable to test myself at the moment

Problem with Left Outer Join In crystal Report

I have the following informations and i want to generate an attendance report per day.I will explain the concept
EMP Table
ID NAME
1 Hassan
2 Hussain
3 Hameed
4 Cruz
5 Philip
Transaction table
EmpID Time
1 5/8/2010 8:00 AM
2 5/8/2010 9:00 AM
3 5/8/2010 10:00 AM
My Attendance Report should look like this
Date:5/8/2010
ID NAME STATUS
1 Hassan Present
2 Hussain Present
3 Hameed Present
4 Cruz Absent
5 Philip Absent
I tried the following ,
1.Created a link wth left outer join ,EMP.ID->transcatio.EmpID
2.Group by date from transation table
Created aformula for status,looks like this
If IsNull({transaction.EmpID}) then 'Absent' else 'Present'
But the report displays only those employees,having transactions on that date.
The report looks like this,
ID NAME STATUS
1 Hassan Present
2 Hussain Present
3 Hammed Present
It seeems that,the left outer join didn't work.
Thanks in advance for any help/advice you can give.
Did you look at the actual SQL query that was generated? Go to Database-->Show SQL Query to see it. It may also be helpful to not use a group by date and see what shows up.
Try a right outer join using the same information that will tell you that it did it in the opposite direction of what you wanted.
Have you set the join to be enforced? Stack Overflow Enforced Link Discussion
When you want to join two tables in crystal report with left out join and at the same time want to filter report based on right table e.g. ORDER.ORDER_DATE>='1-JAN-2014' the join will be converted to equi join
to solve the problem some people suggest to use
(ISNULL(ORDER.ORDER_DATE) OR ORDER.RDER_DATE>='1-JAN-2014')
The above solution only works when there are 0 orders for customer and you still want to show those custer but what if some customer have more than 0 orders and orders date is ON or BEFORE '31-DEC-2013'. In such situation ISNULL(ORDER.ORDER_DATE) will not work. to solve such problem you need to either add command object or create a view for orders table as following
Create command object with following sql
Select Customer.customer_name,Order.Order_id, order.order_date
from customer left outer join order on customer.customer_id=order.Customer_id and order.order_date>='1-JAN-2014'
second solution is to create a view for orders as
create or replace view view_orderrs as
Select * from oders where order.order_dt>='1-JAN-2014'
and then use the view in the report instead of order table as the right table.

Resources