Multiple left outer join with same table allowed? - sql

I tried to convert below SQL in a more optimized way but it is giving error "Operand type clash: uniqueidentifier is incompatible with int". Could you please help me out
select E.EHOId, E.ReferenceId 'ReferenceNo',
(select Comp_Name from FoodAlertCRM.dbo.vCompanyPE where Comp_CompanyId = E.GroupId) 'Group',
(select Comp_Name from FoodAlertCRM.dbo.vCompanyPE where Comp_CompanyId = E.SiteId) 'Site',
E.VisitDate as 'VisitDate',
(select Name from EHO_Dropdowns where ID = E.FollowupAction) 'FollowupAction',
(select Name from EHO_LocalAuthority where ID = E.LocalAuthority) 'LocalAuthority',
(select Name from EHO_Dropdowns where ID = E.[Status]) 'Status',
(select Name from EHO_Dropdowns where ID = E.Position) 'Position',
(select Name from EHO_Dropdowns where ID = E.Structural) 'Structural',
(select Name from EHO_Dropdowns where ID = E.ConfidenceinManagement) 'ConfideninManagement',
(select Name from EHO_Dropdowns where ID = E.HygieneandSafety) 'HygieneandSafety',
(select Name from EHO_Dropdowns where ID = E.RoutineInspection) 'RoutineInspection',
(select Name from EHO_Dropdowns where ID = E.OutcomeofVisit) 'OutcomeofVisit',
e.OfficerName,e.FoodHygieneRating,e.ManageronDuty,e.Comments,
CASE E.AnnouncedVisit
When 0 Then 'No'
When 1 Then 'Yes'
Else ''
ENd as 'AnnouncedVisit',
(select u.Username from FoodAlertCRM.dbo.CDB_User u where u.UserId = e.CreatedBy ) 'CreatedBy',
(select COUNT(EHOId) from EHO_Attachments where EHOId = E.EHOId) as 'AttachmentCount'
from EHO_Log E
where E.IsActive = 1 AND e.IsDeleted = 0
Order by E.VisitDate desc
You see Above has alot of inner queries and performance will be very bad if there are thousand records. so i tried to get rid of inner queries.
select E.EHOId, E.ReferenceId 'ReferenceNo',
(select Comp_Name from FoodAlertCRM.dbo.vCompanyPE where Comp_CompanyId = E.GroupId) 'Group',
(select Comp_Name from FoodAlertCRM.dbo.vCompanyPE where Comp_CompanyId = E.SiteId) 'Site',
E.VisitDate as 'VisitDate',
F.Name 'FollowupAction',L.Name 'LocalAuthority', St.Name 'Status',
P.Name 'Position', S.Name 'Structural', C.Name 'ConfideninManagement',
H.Name 'HygieneandSafety', R.Name 'RoutineInspection', O.Name 'OutcomeofVisit',
e.OfficerName,e.FoodHygieneRating,e.ManageronDuty,e.Comments,
CASE E.AnnouncedVisit
When 0 Then 'No'
When 1 Then 'Yes'
Else ''
ENd as 'AnnouncedVisit',
(select u.Username from FoodAlertCRM.dbo.CDB_User u where u.UserId = e.CreatedBy ) 'CreatedBy',
(select COUNT(EHOId) from EHO_Attachments where EHOId = E.EHOId) as 'AttachmentCount'
from EHO_Log E
Left Outer Join EHO_Dropdowns St ON St.Id = E.[Status]
Left Outer Join EHO_Dropdowns F ON F.Id = E.FollowupAction
Left Outer Join EHO_Dropdowns L ON L.Id = E.LocalAuthority
Left Outer Join EHO_Dropdowns P ON P.Id = E.Position
Left Outer Join EHO_Dropdowns S ON S.Id = E.Structural
Left Outer Join EHO_Dropdowns C ON C.Id = E.ConfidenceinManagement
Left Outer Join EHO_Dropdowns H ON H.Id = E.HygieneandSafety
Left Outer Join EHO_Dropdowns R ON R.Id = E.RoutineInspection
Left Outer Join EHO_Dropdowns O ON O.Id = E.OutcomeofVisit
where E.IsActive = 1 AND e.IsDeleted = 0
Order by E.VisitDate desc
Above code failed and i thought multiple Left outer joins are not allowed and i converted it into below query but still it fails
select E.EHOId, E.ReferenceId 'ReferenceNo',
(select Comp_Name from FoodAlertCRM.dbo.vCompanyPE where Comp_CompanyId = E.GroupId) 'Group',
(select Comp_Name from FoodAlertCRM.dbo.vCompanyPE where Comp_CompanyId = E.SiteId) 'Site',
E.VisitDate as 'VisitDate',
D.Name 'FollowupAction',D.Name 'LocalAuthority', D.Name 'Status',
D.Name 'Position', D.Name 'Structural', D.Name 'ConfideninManagement',
D.Name 'HygieneandSafety', D.Name 'RoutineInspection', D.Name 'OutcomeofVisit',
e.OfficerName,e.FoodHygieneRating,e.ManageronDuty,e.Comments,
CASE E.AnnouncedVisit
When 0 Then 'No'
When 1 Then 'Yes'
Else ''
ENd as 'AnnouncedVisit',
(select u.Username from FoodAlertCRM.dbo.CDB_User u where u.UserId = e.CreatedBy ) 'CreatedBy',
(select COUNT(EHOId) from EHO_Attachments where EHOId = E.EHOId) as 'AttachmentCount'
from EHO_Log E
Left Outer Join EHO_Dropdowns D ON D.Id = E.[Status] AND D.Id = E.FollowupAction
AND D.Id = E.LocalAuthority AND D.Id = E.Position AND D.Id = E.Structural
AND D.Id = E.ConfidenceinManagement AND D.Id = E.HygieneandSafety
AND D.Id = E.RoutineInspection AND D.Id = E.OutcomeofVisit
where E.IsActive = 1 AND e.IsDeleted = 0
Order by E.VisitDate desc
Any idea guys? both of the new queries return error "Operand type clash: uniqueidentifier is incompatible with int".

I think the cause may be this line:
Left Outer Join EHO_Dropdowns L ON L.Id = E.LocalAuthority
Try changing it to be:
Left Outer Join EHO_LocalAuthority L ON L.Id = E.LocalAuthority

Mulitple Outer Join on Same Table :
Solution:
please use nvl on outer join fields
NVL(EHO_Dropdowns(+),EHO_LocalAuthority(+)) = E.LocalAuthority

Related

remove and sum duplicate row in sql, can anyone give me insight for my query?

My query are like this
SELECT
A."name" AS so_name,
CASE
WHEN COUNT(*) OVER (PARTITION BY A."name") > 1
THEN CONCAT('duplicate')
ELSE CONCAT('is unique')
END AS tags,
e.total_qty AS sc_qty,
(SELECT DISTINCT (COALESCE(e.amount_total) * COALESCE (ai.base_currency_rate, 1))
FROM account_invoice ai
JOIN invoice_sale_rel isr ON isr.invoice_id = ai.ID
WHERE isr.sale_id = e.ID) AS sc_total
FROM
sale_quotation A
JOIN
res_partner b ON b.ID = A.partner_id
JOIN
sale_order e ON e.quotation_id = A.ID
LEFT JOIN
res_users C ON C.ID = A.user_id
LEFT JOIN
res_partner d ON d.ID = C.partner_id
WHERE
A.STATE != 'cancel'
AND e.STATE != 'cancel'
AND e.is_merchant = TRUE
ORDER BY
A.NAME ASC
And this is the result:
I am expecting the result would be like this, and add another values too
You need SUM() and GROUP BY
SELECT
A."name" AS so_name,
'is unique' AS tags,
SUM(e.total_qty) AS sc_qty /*,
(SELECT DISTINCT (COALESCE(e.amount_total) * COALESCE (ai.base_currency_rate, 1))*/
FROM account_invoice ai
JOIN invoice_sale_rel isr ON isr.invoice_id = ai.ID
WHERE isr.sale_id = e.ID) AS sc_total
FROM
sale_quotation A
JOIN
res_partner b ON b.ID = A.partner_id
JOIN
sale_order e ON e.quotation_id = A.ID
LEFT JOIN
res_users C ON C.ID = A.user_id
LEFT JOIN
res_partner d ON d.ID = C.partner_id
WHERE
A.STATE != 'cancel'
AND e.STATE != 'cancel'
AND e.is_merchant = TRUE
GROUP BY
A.NAME
ORDER BY
A.NAME ASC

Error In My Code : A TOP N or FETCH rowcount value may not be negative

I am getting this error > A TOP N or FETCH rowcount value may not be negative.
I am getting this error in this section of the code. Please Help >>
Select
A2.Employee_Name,
A2.User_Name,
A2.User_Code,
A2.User_Type_Name,
A2.Region_Name,
A2.Region_Code,
A2.Division_Name,
[A3.Day_Count]-[A2.Sunday]-[A2.Holiday] "Total_Days",
IsNull(A4.Reported_Days,0) "Reported_Days",
IsNUll((A5.Non_Reported_Days)-IsNull((A6.Holiday_Count),0),0) "Non_Reported_Days",
Round((Convert(Float,(A4.Reported_Days))/Convert(Float,((A3.Day_Count)-(A2.Sunday)-(A2.Holiday)))*100),0) "Percentage"
From
(
Select
A1.Employee_Name,
A1.User_Name,
A1.User_Code,
A1.User_Type_Name,
A1.Region_Name,
A1.Region_Code,
A1.Division_Name,
Sum(Case When A1.Days = 1 And A1.Holiday = ''0'' Then 1 Else 0 End) "Sunday",
Sum(Case When A1.Holiday <> ''0'' Then 1 Else 0 End) "Holiday"
From
(
Select
E.Employee_Name,
U.User_Code,
U.User_Name,
UT.User_Type_Name,
R.Region_Name,
R.Region_Code,
D.Division_Name,
Datepart(W,D1.Date_Val) "Days",
IsNull(H.Holiday_Name,0)"Holiday"
From
Tbl_Sfa_User_Master U With(Nolock)
Inner Join Tbl_Sfa_Employee_Master E With(Nolock) On (E.Employee_Code = U.Employee_Code)
Inner Join Tbl_Sfa_User_Type_Master UT With(Nolock) On (UT.User_Type_Code = U.User_Type_Code and UT.User_Type_Category <> ''NON_FIELD_USER'')
Inner Join Tbl_Sfa_Region_Master R With(Nolock) On (R.Region_Code = U.Region_Code And R.Region_Status=1)
Inner Join Tbl_Sfa_Division_Entity_Mapping DE With(Nolock) On (DE.Entity_Code = U.User_Code And DE.Entity_Type=''User'')
Inner Join Tbl_Sfa_Division_Master D With(Nolock) On (D.Division_Code = DE.Division_Code And D.Record_Status=1'
If #Division_Name <> ''
Set #Ins_Tbl = #Ins_Tbl + 'And D.Division_Name ='''+#Division_Name+''' '
Set #Ins_Tbl = #Ins_Tbl +')
Inner Join #DW D1 On (1=1)
Left Outer Join Tbl_Sfa_Holiday_Master H With(Nolock) On (H.Region_Code = R.Region_Code and Convert(Date,H.Holiday_Date) = D1.Date_Val And H.Holiday_Status = 0)
Where U.User_Status=1
)A1
Group By
A1.Employee_Name,
A1.User_Code,
A1.User_Name,
A1.User_Type_Name,
A1.Region_Name,
A1.Region_Code,
A1.Division_Name)A2
Left Outer Join
(Select
B.User_Code,
Count(A.Date_Val) "Day_Count"
From
#DW A
Inner Join Tbl_Sfa_User_Master B With(Nolock) On (1=1)
Where B.User_Status=1
Group By B.User_Code) A3 On (A3.User_Code = A2.User_Code)
Left Outer Join
(Select
U.User_Code,
Count(Distinct D.DCR_Code) "Reported_Days"
From
#R_Days A
Inner Join Tbl_sfa_User_Master U With(Nolock) On (1=1)
Inner Join Tbl_Sfa_User_Type_Master UT With(Nolock) On (UT.User_Type_Code = U.User_Type_Code And User_Type_Category <> ''NON_FIELD_USER'')
Inner Join Tbl_Sfa_DCR_Master D With(Nolock) On (D.User_Code = U.User_Code And D.DCR_Actual_Date = A.Date_Val And D.DCR_Status In (''1'',''2''))
Where U.User_Status=1
Group By U.User_Code)A4 On (A4.User_Code = A2.User_Code)
Left Outer Join
(Select
U.User_Code,
Sum(Case When A.Date_Val=D.DCR_Actual_Date Then 0 Else 1 End) "Non_Reported_Days"
From
#R_Days A
Inner Join Tbl_sfa_User_Master U With(Nolock) On (1=1)
Inner Join Tbl_Sfa_User_Type_Master UT With(Nolock) On (UT.User_Type_Code = U.User_Type_Code And User_Type_Category <> ''NON_FIELD_USER'')
Left Outer Join Tbl_Sfa_DCR_Master D With(Nolock) On (D.User_Code = U.User_Code And D.DCR_Actual_Date = A.Date_Val And D.DCR_Status In (''1'',''2''))
Where U.User_Status=1
Group By U.User_Code)A5 On (A5.User_Code = A2.User_Code)
Left Outer Join
(Select
U.User_Code,
Count(H.Holiday_Code) "Holiday_Count"
From
Tbl_Sfa_User_Master U
Inner Join Tbl_Sfa_Region_Master R On (R.Region_Code = U.Region_Code And R.Region_Status=1)
Inner Join Tbl_Sfa_Holiday_Master H On (H.Region_Code = R.Region_Code And H.Holiday_Date Between '''+#Start_Date+''' and '''+#End_Date+''' and H.Holiday_Status=''0'')
Where U.User_Status=1
Group By
U.User_Code)A6 On (A6.User_Code = A5.User_Code)
looks like the issue is here with the syntax,
Set #Ins_Tbl = #Ins_Tbl + 'And D.Division_Name ='''+#Division_Name+''' '
you should have a space between ' and And as,
Set #Ins_Tbl = #Ins_Tbl + ' And D.Division_Name ='''+#Division_Name+''' '
try it if this works

Moodle SCORM SQL

What table and field I need to use in SQL to find SCORM activities that reports back score to Moodle and exclude the SCORM objects that are set as non scoring. Basically looking for the SCORM settings field: Require Minimum Score in SQL
The query:
SELECT
CONCAT(u.firstname,' ',u.lastname ) AS 'fullname',
cc.name AS 'Category',
c.fullname AS 'Course',
gi.itemname AS 'Item Name',
ROUND(gg.finalgrade / gg.rawgrademax * 100 ,2) AS 'Percentage',
asgm.status as 'Status',
p.status AS 'Completed',
gi.itemmodule as 'Type',
s.completionscorerequired AS require_minimum_score
FROM prefix_course AS c
JOIN prefix_course_categories AS cc ON cc.id = c.category
JOIN prefix_context AS ctx ON c.id = ctx.instanceid
JOIN prefix_role_assignments AS ra ON ra.contextid = ctx.id
JOIN prefix_user AS u ON u.id = ra.userid
JOIN prefix_grade_items AS gi ON gi.courseid = c.id
JOIN prefix_scorm AS s ON c.id = s.course
LEFT JOIN prefix_grade_grades AS gg ON gi.id = gg.itemid AND gg.userid = u.id
LEFT JOIN prefix_course_completions AS p ON p.userid = u.id AND p.course = c.id
LEFT JOIN (
SELECT asgm.status as status, c.id as cid, u.id as uid, gi.id as giid
FROM prefix_course AS c
JOIN prefix_course_categories AS cc ON cc.id = c.category
JOIN prefix_context AS ctx ON c.id = ctx.instanceid
JOIN prefix_role_assignments AS ra ON ra.contextid = ctx.id
JOIN prefix_user AS u ON u.id = ra.userid
JOIN prefix_grade_items AS gi ON gi.courseid = c.id
JOIN prefix_assign AS asg ON gi.iteminstance = asg.id and asg.course = c.id
JOIN prefix_assign_submission AS asgm ON asg.id = asgm.assignment and asgm.userid = u.id
) AS asgm ON c.id = asgm.cid and u.id = asgm.uid and gi.id = asgm.giid
WHERE (gi.itemmodule = 'quiz' OR gi.itemmodule= 'assign' OR gi.itemmodule= 'scorm') AND c.visible=1
SELECT s.id AS scormid, s.name AS scormname,
s.completionscorerequired AS require_minimum_score,
c.id AS courseid, c.fullname AS coursename
FROM mdl_scorm s
JOIN mdl_course c ON c.id = s.course

Subquery in from clause, Invalid Identifier in Where clause

select * from iiasa_inventory.inv_device d
join iiasa_inventory.inv_type ty on d.type_id = ty.id
join iiasa_inventory.inv_category c on ty.category_id = c.id
join iiasa_inventory.inv_device_2_barcode b on b.device_id = d.id
join iiasa_inventory.inv_barcodes bc on b.barcode_id = bc.id
join iiasa_inventory.inv_status s on d.status = s.id
join iiasa_inventory.inv_brand br on ty.brand_id = br.id
left join iiasa_inventory.inv_supplier su on su.id = d.supplier_id
left join iiasa_inventory.inv_supplier sup on sup.id = d.maintenance_with
left join (select distinct device_id from
iiasa_inventory.inv_device_2_persons_cc) dp
on dp.device_id = d.id
where dp.active = 1
I am trying to select my data but the where-clause says that "dp.active" is an INVALID Identifier. This is probably because the table dp is in the subquery. I have tried to give it an alias name and some other things I found while browsing stackoverflow, but I cant seem to find a solution. Any idea?
This is Oracle PL/SQL.
Put the check for active = 1 in the subquery as shown below.
select * from iiasa_inventory.inv_device d
join iiasa_inventory.inv_type ty on d.type_id = ty.id
join iiasa_inventory.inv_category c on ty.category_id = c.id
join iiasa_inventory.inv_device_2_barcode b on b.device_id = d.id
join iiasa_inventory.inv_barcodes bc on b.barcode_id = bc.id
join iiasa_inventory.inv_status s on d.status = s.id
join iiasa_inventory.inv_brand br on ty.brand_id = br.id
left join iiasa_inventory.inv_supplier su on su.id = d.supplier_id
left join iiasa_inventory.inv_supplier sup on sup.id = d.maintenance_with
left join (select distinct device_id from iiasa_inventory.inv_device_2_persons_cc where active = 1) dp on dp.device_id = d.id
That is because you are not selecting active column in dp.
select * from iiasa_inventory.inv_device d
join iiasa_inventory.inv_type ty on d.type_id = ty.id
join iiasa_inventory.inv_category c on ty.category_id = c.id
join iiasa_inventory.inv_device_2_barcode b on b.device_id = d.id
join iiasa_inventory.inv_barcodes bc on b.barcode_id = bc.id
join iiasa_inventory.inv_status s on d.status = s.id
join iiasa_inventory.inv_brand br on ty.brand_id = br.id
left join iiasa_inventory.inv_supplier su on su.id = d.supplier_id
left join iiasa_inventory.inv_supplier sup on sup.id = d.maintenance_with
left join (select distinct device_id,active from iiasa_inventory.inv_device_2_persons_cc) dp on dp.device_id = d.id
where dp.active = 1
OR you can just filter from the subquery itself. Like:
left join (select distinct device_id
from iiasa_inventory.inv_device_2_persons_cc
where active=1) dp on dp.device_id = d.id

Conditional INNER JOIN in SQL Server

I have a rather complex query that pretty much mimics a test query I have below:
SELECT C.*
FROM Customer C
INNER JOIN CustDetail CD ON C.CustomerId = CD.CustomerId
INNER JOIN Address A ON CD.DetailID = A.DetailID
INNER JOIN Group G ON C.CustomerId = G.CustomerId --Join only when C.code = 1
INNER JOIN GroupDetail D ON G.GroupId = D.DetailId --Join only when C.code = 1
WHERE G.Active = 1 AND --Only when C.code = 1
D.code = '1' AND --Only when C.code = 1
C.Id = #customerId
I'd like to do INNER JOINs on Group G and GroupDetail D (and ofcourse not have them in the WHERE conditions based on the table column C.code = 1
I replaced the INNER JOINs with LEFT OUTER JOINs for both the join conditions, but the result set is not what was expected
How do I conditionally do the JOIN
SELECT C.*
FROM Customer C
INNER JOIN CustDetail CD ON C.CustomerId = CD.CustomerId
INNER JOIN Address A ON CD.DetailID = A.DetailID
LEFT OUTER JOIN Group G ON C.CustomerId = G.CustomerId
LEFT OUTER JOIN GroupDetail D ON G.GroupId = D.DetailId
WHERE ((G.Active = 1 AND C.code = 1) OR G.Active IS NULL) AND
((D.code = '1' AND C.code = 1) OR D.code IS NULL) AND
C.Id = #customerId
I'm guessing you didn't include the IS NULL checks before so you never got to see rows where C.code <> 1 ?
You should check for NULL on a field that will never be null. This is almost always 'id', but it's not clear that you have a G.id or a D.id.
I'm guessing what you want is just a tighter ON clause, and a compound condition.
SELECT C.*
FROM Customer C
INNER JOIN CustDetail CD ON C.CustomerId = CD.CustomerId
INNER JOIN Address A ON CD.DetailID = A.DetailID
-- the next two joins happen only when c.code=1
-- their columns will be null when there is no match.
LEFT JOIN Group G ON C.CustomerId = G.CustomerId AND C.Code = 1
LEFT JOIN GroupDetail D ON G.GroupId = D.DetailId AND C.Code = 1
WHERE C.Id = #customerId AND --always check this
-- this condition is true if code is null or code isn't 1,
((C.code IS NULL or C.code <> 1)
-- or (if the code is 1), it is true if g.active and d.code
OR (G.Active = 1 AND D.code = '1'))
This will do a semi-join only when code is 1.
SELECT C.*
FROM Customer C
INNER JOIN CustDetail CD
ON C.CustomerId = CD.CustomerId
INNER JOIN Address A
ON CD.DetailID = A.DetailID
WHERE
C.Id = #customerId AND
(c.code != 1 OR
EXISTS(
SELECT NULL
FROM Group G
JOIN GroupDetail D ON G.GroupId = D.DetailId
WHERE
C.CustomerId = G.CustomerId AND
G.Active = 1 AND
D.code = '1'
))