Condition Based Join in SQL Server - sql

I have the following tables
Invoice
Organization
Customer
I'm trying to conditionally join these tables by the following condition: If PTypecd = 'I' then data come from the Customer table And if Ptypecd = 'O' then data come from the Organization table into the Invoice table.
the query i tried so far:
Select
I.PCD, I.PtypeCD,
From
Invoice I
Left Join
Customer C ON I.PCD = C.CustomerCD
Left Join
Organization O ON I>PDC = O.Organization
How does this condition be used in Join?

Here's a query that joins two tables conditionally, in your case you need to join the Customer table when the PTypecd of Invoice is 1 so add another condition for joint statement AND I.PTypecd = 1, and it the other join you need to check wither I.PTypecd = 0 and that will let you join the other table Organization
SELECT I.PCD, I.PtypeCD
FROM Invoice I
LEFT JOIN Customer a ON a.CustomerCD = i.PDC AND I.PTypecd = 1
LEFT JOIN Organization b ON b.Organization = i.PDC AND i.PTypecd = 0;

Related

LEFT JOIN with condition in WHERE clause

SELECT
supplies.id,
supplierId,
supplies.date,
supplies.commodity,
supplier_payments.date AS paymentDate,
FROM
supplies
INNER JOIN suppliers ON suppliers.id = supplies.supplierId
LEFT JOIN supplier_payments ON supplier_payments.supplyId = supplies.id
WHERE supplier_payments.isDeleted = 0 AND supplierId = 1
What I am trying is to get all records from supplies table and related records from supplier_payments but the supplier_payments.isDeleted should be equal to 0. What happens now that I only get records from supplies that have at least one supplier payment because of the condition. Is there a way to get all supply records and supply payments with condition?
Consider moving the condition on the LEFT JOINed table to the ON clause of the JOIN:
SELECT
sr.id,
se.supplierId,
se.date,
se.commodity,
sp.date AS paymentDate,
FROM supplies se
INNER JOIN suppliers sr ON sr.id = se.supplierId
LEFT JOIN supplier_payments sp
ON sp.supplyId = se.id
AND sp.isDeleted = 0
WHERE se.supplierId = 1
Side notes:
in a multi-table query, always qualify each column with the table it belongs to, to make the query easier to follow and avoid ambiguity
table aliases make the query easier to read and write

SQL statement with union join or left join

database table
I have this SQL problem to find the total count of the disable people between 2 table
The condition is I only want to get the ID with appearing in the recipient table
left join graph
I only want to get the total count of the left side data which link together with the a_children
http://sqlfiddle.com/#!9/2ca178/1
SELECT COUNT(*)
FROM recipient r
LEFT JOIN a_children c
ON r.hp_id = c.hp_id
AND c.health='OKU'
WHERE r.disability = 'YES'

Complex SQL Code

I am having trouble with a SQL query that corresponds to multiple different tables. I have written the following code, but it seems to combine every single booking with every invoice rather than finding the specific invoice that matches a specific booking. Any help would be greatly appreciated.
$sql = "SELECT INVOICE.invoice_id,
g.guest_first_name,
g.guest_last_name,
g.booking_num_guests,
g.booking_num_nights,
CURRENCY.currency_name,
INVOICE.invoice_nightly_rate,
INVOICE.invoice_deposit_amount,
INVOICE.invoice_paid,
ACCOUNT.account_name
FROM INVOICE
INNER JOIN BOOKING
ON INVOICE.invoice_booking_id = BOOKING.booking_id
INNER JOIN CURRENCY
ON INVOICE.invoice_currency_id = CURRENCY.currency_id
INNER JOIN ACCOUNT
ON INVOICE.invoice_account_id = ACCOUNT.account_id
INNER JOIN (
SELECT GUEST.guest_first_name,
GUEST.guest_last_name,
BOOKING.booking_num_guests,
BOOKING.booking_num_nights
FROM BOOKING
INNER JOIN GUEST
ON BOOKING.booking_guest_id = GUEST.guest_id) g
ON INVOICE.invoice_booking_id = BOOKING.booking_id";
Since you already joined INVOICE and BOOKING table in the first inner join, the last inner join should be between BOOKING and GUEST table. Change your query to below
$sql = "SELECT
INVOICE.invoice_id,
GUEST.guest_first_name,
GUEST.guest_last_name,
BOOKING.booking_num_guests,
BOOKING.booking_num_nights,
CURRENCY.currency_name,
INVOICE.invoice_nightly_rate,
INVOICE.invoice_deposit_amount,
INVOICE.invoice_paid,
ACCOUNT.account_name
FROM INVOICE
INNER JOIN BOOKING
ON INVOICE.invoice_booking_id = BOOKING.booking_id
INNER JOIN CURRENCY
ON INVOICE.invoice_currency_id = CURRENCY.currency_id
INNER JOIN ACCOUNT
ON INVOICE.invoice_account_id = ACCOUNT.account_id
INNER JOIN GUEST
ON BOOKING.booking_guest_id = GUEST.guest_id";

JOIN Across 3 tables

I am trying to join together 3 tables and potentially retrieve data from any of the columns.
I have a product and a lifestyle and a 'mapping table' that essentially contains references between the 2.
I want to do it properly using joins - but it is proving troublesome. If i use 'WHEREs' it works.
Here it is
This returns more results than I expect - it is probably doing the right thing, just not what I want!
SELECT DISTINCT PROFDESC.*
FROM PROFDESC
INNER JOIN PRODUCT ON PRODFUND.PRODCD = PRODUCT.PRODCD
INNER JOIN PRODFUND ON PRODFUND.PDFDCODE = PROFDESC.PROFREF
WHERE PRODFUND.PDFDTYPE = 2
This works fine but doesn't 'join' the tables.
SELECT DISTINCT PROFDESC.*
FROM PROFDESC, Product, Prodfund
WHERE
PRODFUND.PRODCD = PRODUCT.PRODCD and
PRODFUND.PDFDCODE = PROFDESC.PROFREF
AND PRODFUND.PDFDTYPE = 2;
I believe my first one is literally joining A to B and B to C where as I want the connection to include A to C
any suggestions?
You just need to have the tables in the query previously defined. This should work fine.
SELECT DISTINCT PROFDESC.*
FROM PROFDESC
INNER JOIN PRODFUND ON PRODFUND.PDFDCODE = PROFDESC.PROFREF
INNER JOIN PRODUCT ON PRODFUND.PRODCD = PRODUCT.PRODCD
WHERE PRODFUND.PDFDTYPE = 2
You should use the correct order when joining
SELECT DISTINCT PROFDESC.*
FROM
PROFDESC
INNER JOIN PRODFUND
ON PROFDESC.PROFREF = PRODFUND.PDFDCODE
INNER JOIN PRODUCT
ON PRODFUND.PRODCD = PRODUCT.PRODCD
WHERE
PRODFUND.PDFDTYPE = 2
But why are you joining to PRODUCT? You are not referring to any columns of it. Does the join somehow narrow the result? If not, drop it:
SELECT DISTINCT PROFDESC.*
FROM
PROFDESC
INNER JOIN PRODFUND
ON PROFDESC.PROFREF = PRODFUND.PDFDCODE
WHERE
PRODFUND.PDFDTYPE = 2
Maybe the DISTINCT can be dropped then (depending on the cardinality of the join).

Joining multiple tables and getting multiple attributes from one of them

I'm trying to join multiple tables together for building a report. The report lists a course, revisions made to it, and who requested, made and approved the revisions.
Under requested, made an approved, the values are employee numbers. I'm trying to join my innerjoined table above, with the Employee table so I can list the names (not just employee numbers) of those that requested, made and approved revisions.
This is what I have which I know is totally wrong.
SELECT *
FROM Courses
INNER JOIN CourseRevisions ON CourseRevisions.PELID = Courses.PELID
INNER JOIN CourseGroups ON CourseGroups.CourseGroupID = Courses.CourseGroupID
INNER JOIN [dbo].[OPG_Employees] ON OPG_Employees.EmployeeID = CourseRevisions.UpdatedBy
AND OPG_Employees.EmployeeID = CourseRevisions.ApprovedBy
AND OPG_Employees.EmployeeID = CourseRevisions.RequestedBy
This only returns a single result which just happens to have the same employee ID listed for all 3 (Requested, Approved and Updated)
How would i get it so I can get the table result for individual employees in each?
You have to join to the OPG_Employees table once for each field, i.e. 3 times in the example above. One INNER JOIN to it for UpdatedBy, one INNER JOIN for ApprovedBy, one INNER JOIN for RequestedBy.
Something like so:
SELECT *
FROM Courses
INNER JOIN CourseRevisions ON CourseRevisions.PELID = Courses.PELID
INNER JOIN CourseGroups ON CourseGroups.CourseGroupID = Courses.CourseGroupID
INNER JOIN [dbo].[OPG_Employees] empUpdatedBy ON empUpdatedBy.EmployeeID = CourseRevisions.UpdatedBy
INNER JOIN [dbo].[OPG_Employees] empApprovedBy ON empApprovedBy.EmployeeID = CourseRevisions.ApprovedBy
INNER JOIN [dbo].[OPG_Employees] empRequestedBy ON empRequestedBy.EmployeeID = CourseRevisions.RequestedBy
You need a separate join for each employee being referenced:
SELECT *
FROM Courses INNER JOIN
CourseRevisions
ON CourseRevisions.PELID = Courses.PELID INNER JOIN
CourseGroups
ON CourseGroups.CourseGroupID = Courses.CourseGroupID INNER JOIN
[dbo].[OPG_Employees] UpdateEmp
ON UpdateEmp.EmployeeID = CourseRevisions.UpdatedBy INNER JOIN
[dbo].[OPG_Employees] ApprovedEmp
on OPG_ApprovedEmp.EmployeeID = CourseRevisions.ApprovedBy INNER JOIN
[dbo].[OPG_Employees] RequestedEmp
on RequestedEmp.EmployeeID = CourseRevisions.RequestedBy
Your original formulation required that all three ids be exactly the same.