Concatenate fields and join tables using iReports - sql-server

I'm trying to concatenate two fields in one table and another two fields in another table and using the concatenated value as the primary key to join the tables together.
Due to the fact that the primary key is linked to example 5 different people i need a unique value per person concatenating a policy number with a dep code.
The following is an example of how to run the query with MSSQL (I did not include the full code - just an example).
Alter table [beneficiary] add [Unique] varchar(max)
Update [beneficiary] Set [Unique] =concat([t1.ms_fk],[t1.dep_fk])
Alter table [tsf_claim] add [Unique] varchar(max)
Update [tsf_claim] Set [Unique1] =concat([t5.ms_fk],[t5.dep_fk])
LEFT JOIN [mipbi_dbo.td_beneficiary] t5 ON t1.[Unique] = t5.[Unique1]
I need to include the above in iReports as the final left join and I dont know how to create additional field in iReports. Also note that my iReports is a very old version (3.7.1)
SELECT t1.scheme_fk,t1.ms_fk,t1.dep_fk,t1.pr_fk,t1.tariff_fk,t1.icd10_fk,t1.claimed_amount,t1.benefit_amount,t1.auth_fk,t1.units,t1.paid_date,
t1.claim_date,t1.claim_code,t1.ref_pr_fk,t1.note,t1.cheque_datetime,t1.suspend_until,t1.dr_mem,t1.suspended,
t2.mem_num,t2.xref_num,
t3.icd10_pk,t3.icd10_descr,
t4.claim_code,t4.description,
t5.initials,t5.surname,
FROM mipst_dbo.tsf_claim as t1
LEFT JOIN mipst_dbo.tsf_memxref t2 ON t1. ms_fk = t2.mem_num
LEFT JOIN mipbi_dbo.td_icd10 t3 ON t1.icd10_fk = t3.icd10_pk
LEFT JOIN mipst_dbo.tsd_ccdesc t4 ON t1.claim_code = t4.claim_code::integer
LEFT JOIN mipbi_dbo.td_beneficiary t5 ON t1.ms_fk = t5.ms_pk
WHERE t1.scheme_fk = '75'
GROUP BY t1.scheme_fk,t1.ms_fk,t1.dep_fk,t1.pr_fk,t1.tariff_fk,t1.icd10_fk,t1.claimed_amount,t1.benefit_amount,t1.auth_fk,t1.units,t1.paid_date,
t1.claim_date,t1.claim_code,t1.ref_pr_fk,t1.note,t1.cheque_datetime,t1.suspend_until,t1.dr_mem,t1.suspended,
t2.mem_num,t2.xref_num,
t3.icd10_pk,t3.icd10_descr,
t4.claim_code,t4.description,
t5.initials,t5.surname
By adding the left join 'LEFT JOIN mipbi_dbo.td_beneficiary t5 ON t1.ms_fk = t5.ms_pk' it is not adding the persons name according to the dependant code. It is merely just joining the lines.
In short a policy number is linked to different people with a dependent code, so when joining the information dep 1 should be linked to dep 1 from the second table with the correct name and surname etc.
In table 1 dep 1 can have say 10 lines, so with the current code it is adding all the information for the policy number on the 10 lines and not just the information for dep 1.
Let me know if the above is clearly defined or if you need more information.

I was able to resolve the query by merely
SELECT t1.scheme_fk,t1.ms_fk,t1.dep_fk,t1.pr_fk,t1.tariff_fk,t1.icd10_fk,t1.claimed_amount,t1.benefit_amount,t1.auth_fk,t1.units,t1.paid_date,
t1.claim_date,t1.claim_code,t1.ref_pr_fk,t1.note,t1.cheque_datetime,t1.suspend_until,t1.dr_mem,t1.suspended,
t2.mem_num,t2.xref_num,
t3.icd10_pk,t3.icd10_descr,
t4.claim_code,t4.description,t4.scheme_code,
t5.ms_pk,t5.dep_fk,t5.initials,t5.surname,
t6.narration,t6.key
FROM mipst_dbo.tsf_claim as t1
LEFT JOIN mipst_dbo.tsf_memxref t2 ON t1. ms_fk = t2.mem_num
LEFT JOIN mipbi_dbo.td_icd10 t3 ON t1.icd10_fk = t3.icd10_pk
LEFT JOIN mipst_dbo.tsd_ccdesc t4 ON t1.claim_code = t4.claim_code::integer
LEFT JOIN mipbi_dbo.td_beneficiary t5 ON t1.ms_fk = t5.ms_pk
LEFT JOIN mipst_dbo.tsf_note t6 ON t1.note = t6.key
WHERE t1.scheme_fk = '28' and
t4.scheme_code = '28' and
t1.ms_fk = t5.ms_pk AND
t1.dep_fk =t5.dep_fk
GROUP BY t1.scheme_fk,t1.ms_fk,t1.dep_fk,t1.pr_fk,t1.tariff_fk,t1.icd10_fk,t1.claimed_amount,t1.benefit_amount,t1.auth_fk,t1.units,t1.paid_date,
t1.claim_date,t1.claim_code,t1.ref_pr_fk,t1.note,t1.cheque_datetime,t1.suspend_until,t1.dr_mem,t1.suspended,
t2.mem_num,t2.xref_num,
t3.icd10_pk,t3.icd10_descr,
t4.claim_code,t4.description,t4.scheme_code,
t5.ms_pk,t5.dep_fk,t5.initials,t5.surname,
t6.narration,t6.key
updating the where clause.

Related

IS NULL being ignored

I am trying to run a query in T-SQL to pull back a data set based on a column being null.
This is a simplified version of the code:
SELECT
T1.Col1, T1.Col2,
T1.Col3, T1.Col4
FROM
table1 AS T1
INNER JOIN
table2 AS T2 ON T1.Col2 = T2.Col3
WHERE
T2.Col4 IS NULL
Problem is, the result includes rows where T2.Col4 are NULL and also not NULL, it's like the WHERE clause doesn't exist.
Any ideas would be greatly
UPDATE - full version of code:
SELECT
M.ref
,C.cname
,CL.clname
,C.ccity
,M.productLine
,M.code
,CL.date
,M.dept
,DPT.group
,TK2.tkname
,TK2.tkdept
FROM DB.dbo.manage AS M
OUTER JOIN DB.dbo.ClientManageRelationship AS CMR
ON CMR.RelatedEntityID = M.EntityID
OUTER JOIN DB.dbo.Client AS C
ON C.EntityID = CMR.EntityID
INNER JOIN DB.dbo.ManageCustomerRelationship AS MCR
ON MCR.EntityID = M.EntityID
INNER JOIN DB.dbo.Customer AS CL
ON CL.EntityID = MCR.RelatedID
INNER JOIN DB.dbo.timek AS TK
ON TK.tki = M.tkid
LEFT JOIN (SELECT Group = division, [Department] = newdesc, deptcode FROM DB.csrt.vw_rep_p_l_dept) AS DPT
ON tkdept = DPT.dept
LEFT JOIN (SELECT Name = TK2.tkfirst + ' ' + TK2.tklast, TK2.tki, TK2.dept, TK2.loc FROM DB.dbo.timek as TK2 WITH(NOLOCK)) AS TK2
ON TK2.tki = M.tkid
WHERE DPT.Department = 'Casualty'
AND UPPER (C.ClientName) LIKE '%LIMITED%'
AND CL.date > '31/12/2014'
AND CL.Date IS NULL
AND TK.tkloc = 'loc1' OR TK.tkloc = 'loc2'
ORDER BY M.ref
My first answer would be because you're using INNER JOIN. This only returns matches between the 2 tables. TRY FULL OUTER JOIN which will return all values regardless of matches and will include NULLS.
If you were looking to return all rows regardless of matches including NULLS from only one of the tables then use RIGHT or LEFT JOIN.
Say i had 2 tables ('Person' and 'Figure'). Not every person may have entered a figure on any one day. But an example may be i want to return all people regardless of whether they entered a figure or not on a certain day.
My initial approach to this would be a LEFT join because i want to return of all the people(left table) regardless of there being any matches in the figure table(right table)
FROM Person P
LEFT JOIN Figure F
ON P.ID = F.ID
This would produce a result such as
Name Figure
Sam 20
Ben 30
Matt NULL
Simon NULL
Whereas,
An inner join would produce only matching values not including nulls
Name Figure
Sam 20
Ben 30
Left join works the same way as right join but in the opposite direction. This is most likely the problem you were facing. But i hope this helped
I think the problem is in the last part of the where condition.
You should use brackets.
`WHERE DPT.Department = 'Casualty'
AND UPPER (C.ClientName) LIKE '%LIMITED%'
AND CL.date > '31/12/2014'
AND CL.Date IS NULL
AND (TK.tkloc = 'loc1' OR TK.tkloc = 'loc2')`
or
`WHERE DPT.Department = 'Casualty'
AND UPPER (C.ClientName) LIKE '%LIMITED%'
AND CL.date > '31/12/2014'
AND CL.Date IS NULL
AND TK.tkloc IN ('loc1', 'loc2')`

Left Join multiple tables on a parent table and subtract one column from the parent table

I have 3 tables (donor_detail, items & store) that I left joined on 1 parent table (donated_items), now there is a column quantity in the parent table which I wish to subtract from another table's column which is issued_donation.issued_quantity
here is my SQL which left joins but I am not understanding how should I subtract that column. i.e. donated_items.quantity - issued_donation.issued_quantity
SELECT t1.*, t2.donor_name,t2.ID, t3.ID,t3.item_name, t4.store_name, t4.ID
FROM donated_items as t1
LEFT JOIN donor_detail as t2 ON t1.donor_id = t2.ID
LEFT JOIN items as t3 ON t1.item_id = t3.ID
LEFT JOIN stores as t4 ON t1.store_id = t4.ID
Your question isn't very clear, but I suspect you're talking about subtracting values, not columns. If I'm right, you have to join the other table (issued_donation) and than you can add to the selected fields something like t1.quantity - t5.issued_quantity AS remainingQuantity.

Inner Join and Left Join in same sql query

I'm trying to perform inner join and then left join in same sql query.
But the left join is not working. It is not showing the null values
I've two tables EVENT_INVITATIONS and USERINFO which has 2 records when joined.
so, the join query goes like this :
select * from [UandMePROD].[dbo].EVENT_INVITATIONS EI
join [UandMePROD].[dbo].USERINFO UI on EI.USER_ID = UI.USER_ID and EI.EVENT_ID=11033
It gives out 2 records.
So, I'm performing a left join with another table CLIENT_CONTACTS which has only 1 matching record in it.
So, actually it should show the null value to the unmatched record. but it is not showing the second record. It is showing only 1 record which is matched(join)
My failed sql query :
select * from [UandMePROD].[dbo].EVENT_INVITATIONS EI
join [UandMePROD].[dbo].USERINFO UI on EI.USER_ID = UI.USER_ID
left join CLIENT_CONTACTS CC on UI.MOBILENO=CC.MOBILE_NUMBER
where cc.CLIENT_ID=20111 and EI.EVENT_ID=11033
can you please tell me where I'm doing mistake?
I need the 2 records.
Since you are doing a left join, cc.CLIENT_ID is null for all the values which only exist in CLIENT_CONTACTS and your where clause Where cc.CLIENT_ID = 20111
converts your LEFT JOIN into INNER JOIN. Adding this filter in ON clause solves the issue.
select *
from [UandMePROD].[dbo].EVENT_INVITATIONS EI
inner join [UandMePROD].[dbo].USERINFO UI on EI.[USER_ID] = UI.[USER_ID]
left join CLIENT_CONTACTS CC on UI.MOBILENO = CC.MOBILE_NUMBER
and cc.CLIENT_ID = 20111
where EI.EVENT_ID=11033
You should not specify EI.EVENT_ID on WHERE clause. Those limit your results after the join. You should specify EI.EVENT_ID in an ON clause.
select * from [UandMePROD].[dbo].EVENT_INVITATIONS EI join [UandMePROD].[dbo].USERINFO UI on EI.USER_ID = UI.USER_ID AND (EI.EVENT_ID=11033 or EI.EVENT_ID is null) left join CLIENT_CONTACTS CC on UI.MOBILENO=CC.MOBILE_NUMBER where cc.CLIENT_ID=20111
Providing some suggestions,since it is not possible to say what is happening with out table data
Left join should show null values from output of first inner join eventhough there are no mobile number matches,so try removing where condition and see if you are getting any result

Many left join on the same table

I have a table in 2 different database. Table1 in DataBase1 and Table2 in database2.
Table1 and Table2 have the same columns with different rows content.
each row correspond to a parcel number (TShipping_Tracking or TShipping_Reference or TShipping_OrderRef or TShipping_Barcode) and an ID (TShipping_ID). Remarque: for each parcel (row) only 1 of the 4 column , related to parcel number, listed above is not null
These are the schema of the table in each database:
create table Database1..Table1 (TShipping_ID varchar(50),TShipping_Tracking varchar(50),TShipping_Reference varchar(50),TShipping_OrderRef varchar(50),TShipping_Barcode varchar(50))
create table Database2..Table2 (TShipping_ID varchar(50),TShipping_Tracking varchar(50),TShipping_Reference varchar(50),TShipping_OrderRef varchar(50),TShipping_Barcode varchar(50))
Moreover, I have the table Database1..Reject having the same columns as Table1 (and Table2) exept TShipping_ID:
create table Database1..Table3(TShipping_Tracking varchar(50),TShipping_Reference varchar(50),TShipping_OrderRef varchar(50),TShipping_Barcode varchar(50))
I want to retreive TShipping_ID of the parcel that does not exist in Database1
I did the following query but it has a very bad response time:
select isnull(isnull(isnull(D2t1 .TShipping_ID,D2t2.TShipping_ID),D2t3.tshipping_id),D2t4.tshipping_id) as TShipping_ID
from Database1..Table3 D1t3
left join Database1..Table1 D1t1 on D1t3.TShipping_tracking=D1t1.TShipping_tracking
left join Database1..Table1 D1t2 on D1t3.TShipping_Reference=D1t2.TShipping_Reference
left join Database1..Table1 D1t3 on D1t3.TShipping_OrderRef=D1t3.TShipping_OrderRef
left join Database1..Table1 D1t4 on D1t3.TShipping_barcode=D1t4.TShipping_barcode
left join Database2..Table2 D2t1 on D1t3.TShipping_tracking=D2t1.TShipping_tracking
left join Database2..Table2 D2t2 on D1t3.TShipping_Reference=D2t2.TShipping_Reference
left join Database2..Table2 D2t3 on D1t3.TShipping_OrderRef=D2t3.TShipping_OrderRef
left join Database2..Table2 D2t4 on D1t3.TShipping_barcode=D2t4.TShipping_barcode
where D1t1.TShipping_Tracking is null and D1t2.TShipping_Reference is null and D1t3.TShipping_OrderRef is null and D1t4.TShipping_BarCode is null
Does anyone has a better way to do it?
Thanks
Assuming that Table1.TShipping_ID is a NOT NULL field:
SELECT t2.TShipping_ID
FROM Table3 t3
LEFT JOIN Table2 t2
ON t2.TShipping_Tracking = t3.TShipping_Tracking
OR t2.TShipping_Reference = t3.TShipping_Reference
OR t2.TShipping_OrderRef = t3.TShipping_OrderRef
OR t2.TShipping_Barcode = t3.TShipping_Barcode
LEFT JOIN Table2 t1
ON t1.TShipping_Tracking = t3.TShipping_Tracking
OR t1.TShipping_Reference = t3.TShipping_Reference
OR t1.TShipping_OrderRef = t3.TShipping_OrderRef
OR t1.TShipping_Barcode = t3.TShipping_Barcode
WHERE t1.TShipping_ID IS NULL
This will still be slow as hell, not the least of which because it's pretty close to a CROSS JOIN, but you don't supply enough information about what you're doing or what the key fields of the tables are to make me think you can replace the OR with AND in the join conditions. I suspect that may be the case, however.

How to join additional table when left outer not working

I have an existing proc which I have chopped up for brevity's sake
SELECT col1, col2
FROM (
col1, col2
SELECT col3--aggregate columns
FROM iep i
INNER JOIN student s ON s.studentID = i.studentID
INNER JOIN dbo.IDuration id ON i.IepID = id.iepID
INNER JOIN AppointmentStudent as ON s.studentID = as.studentID
INNER JOIN Appointment a ON as.appointmentID = a.appointmentID
INNER JOIN AppointmentTherapist at ON a.appointmentID = at.appointmentID
WHERE s.studentID = #studentID
GROUP BY col1, col2
) t
The aggregate columns summarizes appointments into the weeks of the year, but it only does sos for the weeks the student had appointments. I have an additional table called SchoolWeekYear that is populated with all of the weeks of the year that I am trying to integrate to this proc so I get 52 records back and not just the handful I am currently getting.
SELECT col1, col2
FROM (
col1, col2
SELECT col3--aggregate columns
FROM iep i
INNER JOIN student s ON s.studentID = i.studentID
INNER JOIN dbo.IDuration id ON i.IepID = id.iepID
INNER JOIN AppointmentStudent as ON s.studentID = as.studentID
INNER JOIN Appointment a ON as.appointmentID = a.appointmentID
LEFT OUTER JOIN SchoolWeekYear swy on a.calWeekNumber = swy.calWeekNumber
INNER JOIN AppointmentTherapist at ON a.appointmentID = at.appointmentID
WHERE s.studentID = #studentID
GROUP BY col1, col2
) t
Is this possible?
You need to integrate SchoolWeekYear into the existing table set at an earlier stage.
To show you the principle, let us simplify the problem even further. Let there be a table called WeeklyData with columns WeekNumber and SomeData. Some weeks might have multiple entries, some others none. So this query
SELECT
WeekNumber,
AGG(SomeData)
FROM
WeeklyData
GROUP BY
WeekNumber
;
would return only weeks present in WeeklyData. If you want to return data for all weeks, use a corresponding reference table (let it be called AllWeeks) like this:
SELECT
aw.WeekNumber,
AGG(wd.SomeData)
FROM
AllWeeks AS aw
LEFT JOIN
WeeklyData AS wd ON aw.WeekNumber = wd.WeekNumber
GROUP BY
aw.WeekNumber
;
So, you take the reference table (AllWeeks) and join the data table (WeeklyData) to it, not the other round.
Now, what if the original query was slightly more complex? Let us now suppose the data table is called StudentWeeklyData and has a column called StudentID which is a reference to a Students table. Let us also imagine the query is similar to yours in that it logically includes the Students table before the data table is joined and filters the results on the primary key of Students:
SELECT
s.StudentID,
s.StudentName,
swd.WeekNumber,
AGG(swd.SomeData)
FROM
Students AS s
INNER JOIN
StudentWeeklyData AS swd ON s.StudentID = swd.StudentID
WHERE
s.StudentID = #StudentID
GROUP BY
s.StudentID,
s.StudentName,
swd.WeekNumber
;
(Not every detail matters here, I just wanted to use a more similar example for you that would still be simple enough to understand.) Again, this would return only weeks where the specified student has data in StudentWeeklyTable. If you wanted to return all weeks for the student (some of them potentially empty, of course), this is how you could go about it:
SELECT
s.StudentID,
s.StudentName,
aw.WeekNumber,
AGG(swd.SomeData)
FROM
Students AS s
CROSS JOIN
AllWeeks AS aw
LEFT JOIN
StudentWeeklyData AS swd ON s.StudentID = swd.StudentID
AND aw.WeekNumber = swd.WeekNumber
WHERE
s.StudentID = #StudentID
GROUP BY
s.StudentID,
s.StudentName,
aw.WeekNumber
;
Here you can see again that the AllWeeks table is included before the data table. The difference to the previous case is we are not left-joining the result of the join between Students and StudentWeekly to AllWeeks, nor are we left-joining the data table itself specifically to AllWeeks. Instead, the data table is joined to the result of a cross join, Students × AllWeeks.
Returning to your specific situation, I realise that in your case even more tables are involved. Since you are not specifying how all those tables are related to one another, I can only guess that SchoolWeekYear should be cross-joined somewhere after FROM and before this line:
INNER JOIN Appointment a ON as.appointmentID = a.appointmentID
and that the said line should be modified like this:
LEFT JOIN Appointment a ON as.appointmentID = a.appointmentID
AND swy.calWeekNumber = a.calWeekNumber
the swy being an alias assigned to SchoolWeekYear.
It is also worth noting that there is a subsequent inner join with AppointmentTherapist. That join would eliminate the effect of the above left join if it remained unchanged, because its condition references the Appointment table. Perhaps, the syntactically easiest way to fix the issue would be to change that inner join to a left one too, although there is another way: instead of
LEFT JOIN Appointment a ON as.appointmentID = a.appointmentID
AND swy.calWeekNumber = a.calWeekNumber
LEFT JOIN AppointmentTherapist at ON a.appointmentID = at.appointmentID
you could use this syntax:
LEFT JOIN
Appointment a
INNER JOIN AppointmentTherapist at ON a.appointmentID = at.appointmentID
ON as.appointmentID = a.appointmentID
AND swy.calWeekNumber = a.calWeekNumber
That way the logical order of joining would be changed: Appointment and AppointmentTherapist would be first inner-joined with each other, then the result set would be outer-joined to the result of the previously specified joins.
It is possible. But if you have multiple row with some calWeekNumber on the SchoolWeekYear table, your aggregate function return wrong result.
If you want all lines in SchoolWeekYear shown, regardless of a match, you should use RIGHT OUTER JOIN instead of LEFT.

Resources