Query Alternate Table if record not exist - sql

I have two queries as bellow
SELECT i.IncidentId, rl.Description Category FROM incident i
JOIN IncidentLikelihood l ON i.IncidentId = l.IncidentId
JOIN IncidentSeverity s ON i.IncidentId = s.IncidentId
JOIN LikelihoodSeverity ls ON l.LikelihoodId = ls.LikelihoodId AND s.SeverityId = ls.SeverityId
JOIN RiskLevel rl ON ls.RiskLevelId = rl.riskLevelId
And
SELECT i.IncidentId, rl.Description Category FROM incident i
JOIN incidentreportlikelihood l ON i.IncidentId = l.IncidentId
JOIN IncidentReportSeverity s ON i.IncidentId = s.IncidentId
JOIN LikelihoodSeverity ls ON l.LikelihoodId = ls.LikelihoodId AND s.SeverityId = ls.SeverityId
JOIN RiskLevel rl ON ls.RiskLevelId = rl.riskLevelId
I need to prepare a query with WITH clause such that within the clause either of the two query runs and then this view can be joined with another table.
Can you guys please suggest how I can proceed ?
I have tried UNION but that doesn't work for me. I am looking for something using IFEXISTS or EXISTS where - some like bellow :
WITH IncidentCategory AS (
SELECT i.IncidentId, rl.Description Category FROM incident i
JOIN IncidentLikelihood l ON i.IncidentId = l.IncidentId
JOIN IncidentSeverity s ON i.IncidentId = s.IncidentId
JOIN LikelihoodSeverity ls ON l.LikelihoodId = ls.LikelihoodId AND s.SeverityId = ls.SeverityId
JOIN RiskLevel rl ON ls.RiskLevelId = rl.riskLevelId
WHERE EXISTS (SELECT NULL)
OR
(SELECT i.IncidentId, rl.Description Category FROM incident i
JOIN incidentreportlikelihood l ON i.IncidentId = l.IncidentId
JOIN IncidentReportSeverity s ON i.IncidentId = s.IncidentId
JOIN LikelihoodSeverity ls ON l.LikelihoodId = ls.LikelihoodId AND s.SeverityId = ls.SeverityId
JOIN RiskLevel rl ON ls.RiskLevelId = rl.riskLevelId)
)
A little more to get the idea : for each of the rows [incidentid] if the the first query returns any result - it should show otherwise the second query result should show

If I understand the requirements correctly you have to run first query and if it has no results the second one should be run.
In fact you can union the both queries. The amount of rows in the second one should depend on the first. If count(*) for the first returns >0 the second query rows are included. See the example
SELECT i.IncidentId, rl.Description Category FROM incident i
JOIN IncidentLikelihood l ON i.IncidentId = l.IncidentId
JOIN IncidentSeverity s ON i.IncidentId = s.IncidentId
JOIN LikelihoodSeverity ls ON l.LikelihoodId = ls.LikelihoodId AND s.SeverityId = ls.SeverityId
JOIN RiskLevel rl ON ls.RiskLevelId = rl.riskLevelId
UNION
SELECT i.IncidentId, rl.Description Category FROM incident i
JOIN incidentreportlikelihood l ON i.IncidentId = l.IncidentId
JOIN IncidentReportSeverity s ON i.IncidentId = s.IncidentId
JOIN LikelihoodSeverity ls ON l.LikelihoodId = ls.LikelihoodId AND s.SeverityId = ls.SeverityId
JOIN RiskLevel rl ON ls.RiskLevelId = rl.riskLevelId
join (select count(*) as count
FROM incident i
JOIN IncidentLikelihood l ON i.IncidentId = l.IncidentId
JOIN IncidentSeverity s ON i.IncidentId = s.IncidentId
JOIN LikelihoodSeverity ls ON l.LikelihoodId = ls.LikelihoodId AND s.SeverityId = ls.SeverityId
JOIN RiskLevel rl ON ls.RiskLevelId = rl.riskLevelId) q1_copy on q1_copy.count=0

Related

JOIN two SELECT without UNION

It needs to download the ID, name and surname of those who have registered by the deadline and have an identity card (with the relevant conditions) or passport (with the relevant conditions). ID card and passport are two separate tables.
I have made the SQL queries in UNION format and it works:
select distinct p.id, p.name, p.surname from persons.person p
join persons.documents d on d.person_id = p.id
join persons.id_card idd on d.id_card_id = idd.id
join persons.id_card_to_registration ir on idd.id = ir.id_card
join registrations.registration r on ir.registration_id = r.id
where p.created_at >= '2022-01-01'
and p.created_at <= '2022-03-30'
and p.registration_id = r.id
and ir.status in (0,5)
UNION
select distinct p.id, p.name, p.surname from persons.person p
join persons.documents d on d.person_id = p.id
join persons.passport pass on d.passport_id = pass.id
join persons.passport_country pc on pc.id = pass_country_id
join persons.passport_to_registration pr on pass.id = pr.passport_id
join registrations.registration r on pr.registration_id = r.id
where p.created_at >= '2022-01-01'
and p.created_at <= '2022-03-30'
and p.registration_id = r.id
and pc.zone in (0,1) or (pc.zone is null and pass.safe = true);
I would now like to do this SQL in one query without union and unfortunately it doesn't work for me - I tried to do it like this:
select distinct p.id, p.name, p.surname from persons.person p
join persons.documents d on d.person_id = p.id
left join persons.id_card idd on d.id_card_id = idd.id
left join persons.id_card_to_registration ir on idd.id = ir.id_card
left join persons.passport pass on d.passport_id = pass.id
left join persons.passport_country pc on pc.id = pass_country_id
left join persons.passport_to_registration pr on pass.id = pr.passport_id
join registrations.registration r on ir.registration_id = r.id
where p.created_at >= '2022-01-01'
and p.created_at <= '2022-03-30'
and p.registration_id = r.id
and (ir.status in (0,5) or ir.status is null)
and pc.zone in (0,1) or (pc.zone is null and pass.safe = true)
And it doesn't return any records to me. I would like some advice on what error I have made. And is it possible to create such a query without union?
The SQL in clause may help to filter by each condition. This may be the way to avoid the union clause, please let me know if this works for you:
select distinct p.id, p.name, p.surname from persons.person p
where p.created_at >= '2022-01-01'
and p.created_at <= '2022-03-30'
and ((p.id in
(select distinct p2.id from persons.person p2
d.person_id from persons.documents d on d.person_id = p2.id
join persons.id_card idd on d.id_card_id = idd.id
join persons.id_card_to_registration ir on idd.id = ir.id_card
join registrations.registration r on ir.registration_id = r.id
where p2.registration_id = r.id
and ir.status in (0,5)
)
) or (
(p.id in
(select distinct p3.id from persons.person p3
d.person_id from persons.documents d on d.person_id = p3.id
join persons.passport pass on d.passport_id = pass.id
join persons.passport_country pc on pc.id = pass_country_id
join persons.passport_to_registration pr on pass.id = pr.passport_id
join registrations.registration r on pr.registration_id = r.id
where p3.registration_id = r.id
and pc.zone in (0,1) or (pc.zone is null and pass.safe = true);
)
)
))
I think you'll have better performance if you can convert the query to use EXISTS.
SELECT DISTINCT p.id, p.name, p.surname
FROM persons.person p
WHERE p.created_at >= '2022-01-01'
AND p.created_at <= '2022-03-30'
AND(EXISTS (SELECT *
FROM persons.documents d
JOIN persons.id_card idd
ON d.id_card_id = idd.id
JOIN persons.id_card_to_registration ir
ON idd.id = ir.id_card
JOIN registrations.registration r
ON ir.registration_id = r.id
WHERE p.id = d.person_id
AND p.registration_id = r.id
AND ir.status IN (0,5))
OR EXISTS (SELECT *
FROM persons.documents d
JOIN persons.passport pass
ON d.passport_id = pass.id
JOIN persons.passport_country pc
ON pc.id = pass_country_id
JOIN persons.passport_to_registration pr
ON pass.id = pr.passport_id
JOIN registrations.registration r
ON pr.registration_id = r.id
WHERE p.id = d.person_id
AND p.registration_id = r.id
AND pc.zone IN (0,1)
OR (pc.zone IS NULL
AND pass.safe = TRUE)))

SQL SERVER:(performance issue) get all rows and if the column is duplicated select the max row of another column from the select statement

I've written the below code to get the max ACUTAL_SHIP_DATE value if the PLANT column values are duplicated and it is working as expected.
SELECT A.PLANT,
A.SLOT_NUM,
A.CONSUMPTIONENDITEM,
A.SALESORDERNUMBER,
A.SOLINEITEM,
A.ACUTAL_SHIP_DATE
FROM (SELECT TOP 10
P.SLOT_NUM,
P.PLANT,
P.CONSUMPTIONENDITEM,
P.SALESORDERNUMBER,
P.SOLINEITEM,
T.SHIP_ACTUAL_DATE AS ACUTAL_SHIP_DATE
FROM SRTPROJECT P WITH (NOLOCK)
INNER JOIN V_SRT_TOOLINFO_CM T WITH (NOLOCK) ON P.SLOT_NUM = T.SLOT_NUM
AND P.PLANT = T.PLANT
AND P.CONSUMPTIONENDITEM = T.MAT_NUM) A
INNER JOIN (SELECT DI.PLANT,
MAX(DI.ACUTAL_SHIP_DATE) AS ACUTAL_SHIP_DATE
FROM (SELECT TOP 10
P.SLOT_NUM,
P.PLANT,
P.CONSUMPTIONENDITEM,
P.SALESORDERNUMBER,
P.SOLINEITEM,
T.SHIP_ACTUAL_DATE AS ACUTAL_SHIP_DATE
FROM SRTPROJECT P WITH (NOLOCK)
INNER JOIN V_SRT_TOOLINFO_CM T WITH (NOLOCK) ON P.SLOT_NUM = T.SLOT_NUM
AND P.PLANT = T.PLANT
AND P.CONSUMPTIONENDITEM = T.MAT_NUM) DI
GROUP BY DI.PLANT) B ON A.PLANT = B.PLANT
AND A.ACUTAL_SHIP_DATE = B.ACUTAL_SHIP_DATE;
in the above query
Step1: Fetching the data from two tables and making collection.
SELECT TOP 10
P.SLOT_NUM,
P.PLANT,
P.CONSUMPTIONENDITEM,
P.SALESORDERNUMBER,
P.SOLINEITEM,
T.SHIP_ACTUAL_DATE AS ACUTAL_SHIP_DATE
FROM SRTPROJECT P WITH (NOLOCK)
INNER JOIN V_SRT_TOOLINFO_CM T WITH (NOLOCK) ON P.SLOT_NUM = T.SLOT_NUM
AND P.PLANT = T.PLANT
AND P.CONSUMPTIONENDITEM = T.MAT_NUM;
Step2: Applying Max if the PLANT column value is duplicated
(SELECT TOP 10 P.SLOT_NUM, P.PLANT, P.CONSUMPTIONENDITEM, P.SALESORDERNUMBER, P.SOLINEITEM,T.SHIP_ACTUAL_DATE AS ACUTAL_SHIP_DATE FROM SRTPROJECT P WITH (NOLOCK) INNER JOIN V_SRT_TOOLINFO_CM T WITH (NOLOCK) ON P.SLOT_NUM = T.SLOT_NUM AND P.PLANT = T.PLANT AND P.CONSUMPTIONENDITEM = T.MAT_NUM) AS A INNER JOIN (Select DI.PLANT, MAX(DI.ACUTAL_SHIP_DATE) AS ACUTAL_SHIP_DATE From (SELECT TOP 10 P.SLOT_NUM, P.PLANT, P.CONSUMPTIONENDITEM, P.SALESORDERNUMBER, P.SOLINEITEM, T.SHIP_ACTUAL_DATE AS ACUTAL_SHIP_DATE FROM SRTPROJECT P WITH (NOLOCK) INNER JOIN V_SRT_TOOLINFO_CM T WITH (NOLOCK) ON P.SLOT_NUM = T.SLOT_NUM AND P.PLANT T.PLANT AND P.CONSUMPTIONENDITEM = T.MAT_NUM) AS DI GROUP BY DI.PLANT)
Step3: then selecting all the columns which is required with the final query which is written initially
but the problem is I'm using same subquery twice. is there any way to remove the duplicate code.
I think this is what you want, but I have not tested it because you do not provide sample data:
with cte
as
(
SELECT TOP 10
P.SLOT_NUM,
P.PLANT,
P.CONSUMPTIONENDITEM,
P.SALESORDERNUMBER,
P.SOLINEITEM,
T.SHIP_ACTUAL_DATE AS ACUTAL_SHIP_DATE
FROM SRTPROJECT P WITH (NOLOCK)
INNER JOIN V_SRT_TOOLINFO_CM T WITH (NOLOCK) ON P.SLOT_NUM = T.SLOT_NUM
AND P.PLANT = T.PLANT
AND P.CONSUMPTIONENDITEM = T.MAT_NUM
)
SELECT A.PLANT,
A.SLOT_NUM,
A.CONSUMPTIONENDITEM,
A.SALESORDERNUMBER,
A.SOLINEITEM,
A.ACUTAL_SHIP_DATE
FROM cte A
INNER JOIN (SELECT DI.PLANT,
MAX(DI.ACUTAL_SHIP_DATE) AS ACUTAL_SHIP_DATE
FROM cte DI
GROUP BY DI.PLANT) B ON A.PLANT = B.PLANT
AND A.ACUTAL_SHIP_DATE = B.ACUTAL_SHIP_DATE;
It just uses WITH to create "cte" so you do not have to execute the same query twice.
You should try to provide minimal reproductible examples, with sample data and expected results. This way it would be easier to help you

Remove Almost Duplicate Rows in SQL from a select query

I'm trying to select some data but I'm getting 'almost duplicated rows' -
all of the columns are the same except the 'gtin' column, the result I'm expecting is to get only one line of each of those 'almost duplicated rows'
The result I'm trying to achieve is to only get row 1 & 3.
this is the query I'm using:
SELECT DISTINCT 'Y' AS isEnterprise,
ii.ITEM_ID AS itemId,
ii.PARENT_ITEM_ID as PID,
ii.ITEM_IDENTIFIER AS productNo,
id.DESCRIPTION_1 AS description,
id.DESCRIPTION_4 AS packValue,
pid.PACKAGE_IDENTIFIER AS gtin,
pac.PRE_PRICE_AMOUNT AS eachPrice
FROM PWRNXGDTA.ITEM_INFORMATION AS ii
JOIN PWRNXGDTA.ITEM_ASSORTMENT AS ia ON ii.ITEM_ID = ia.ITEM_ID
JOIN PWRNXGDTA.ITEM_DESCRIPTION AS id ON id.ITEM_ID = ii.ITEM_ID
JOIN PWRNXGDTA.BUSINESS_UNIT AS bu ON ii.LOGISTICS_BU_ID = bu.BU_ID
LEFT JOIN PWRNXGDTA.ITEM_EXTN_NONMDM AS ien ON ien.ITEM_IDENTIFIER = ii.ITEM_IDENTIFIER
LEFT JOIN PWRNXGDTA.LKP_CLASSIFICATION_CLASS AS lcc ON lcc.CLASSIFICATION_CLASS_ID = ii.CLASSIFICATION_CLASS_ID
LEFT JOIN PWRNXGDTA.LKP_CLASSIFICATION_PBH AS lcp ON lcp.CLASSIFICATION_PBH_ID = ii.CLASSIFICATION_PBH_ID
LEFT JOIN PWRNXGDTA.LKP_CLASSIFICATION_PBHF AS lcpf ON lcpf.CLASSIFICATION_PBHF_ID = ii.CLASSIFICATION_PBHF_ID
LEFT JOIN PWRNXGDTA.LIST_PROPRIETARY_ITEM AS lpi ON lpi.ITEM_IDENTIFIER = ii.ITEM_IDENTIFIER
JOIN PWRNXGDTA.PA_ASSORTMENT AS pa ON pa.PACKAGE_ASSORTMENT_ID = ia.PACKAGE_ASSORTMENT_ID
JOIN PWRNXGDTA.ITEM_PRODUCT AS ip ON ip.ITEM_ID = ii.ITEM_ID
JOIN PWRNXGDTA.PRODUCT_INFO AS pin ON pin.PRODUCT_ID = ip.PRODUCT_ID
LEFT JOIN PWRNXGDTA.PRODUCT_NUTRITIONAL AS pn ON pn.PRODUCT_ID = ip.PRODUCT_ID
LEFT JOIN PWRNXGDTA.LKP_BRAND_INFORMATION AS lbi ON lbi.BRAND_ID = pin.BRAND_ID
AND lbi.RECORD_STATUS = 'A'
JOIN PWRNXGDTA.PACKAGE_IDENTIFIER AS pid ON pid.PACKAGE_ID = pa.PACKAGE_ID
JOIN PWRNXGDTA.PA_CONSUMABLE AS pac ON pac.PACKAGE_ASSORTMENT_ID = pa.PACKAGE_ASSORTMENT_ID
where id.DESCRIPTION_1 like '%HAAGEN DAZ VAN MLK CHO BR%'
Please help, thanks.
You can't do it with distinct, since distinct works on full rows only.
Your best option is to use group by:
SELECT 'Y' AS isEnterprise,
ii.ITEM_ID AS itemId,
ii.PARENT_ITEM_ID as PID,
ii.ITEM_IDENTIFIER AS productNo,
id.DESCRIPTION_1 AS description,
id.DESCRIPTION_4 AS packValue,
MIN(pid.PACKAGE_IDENTIFIER) AS gtin, -- Or max, if you want to...
pac.PRE_PRICE_AMOUNT AS eachPrice
FROM PWRNXGDTA.ITEM_INFORMATION AS ii
JOIN PWRNXGDTA.ITEM_ASSORTMENT AS ia ON ii.ITEM_ID = ia.ITEM_ID
JOIN PWRNXGDTA.ITEM_DESCRIPTION AS id ON id.ITEM_ID = ii.ITEM_ID
JOIN PWRNXGDTA.BUSINESS_UNIT AS bu ON ii.LOGISTICS_BU_ID = bu.BU_ID
LEFT JOIN PWRNXGDTA.ITEM_EXTN_NONMDM AS ien ON ien.ITEM_IDENTIFIER = ii.ITEM_IDENTIFIER
LEFT JOIN PWRNXGDTA.LKP_CLASSIFICATION_CLASS AS lcc ON lcc.CLASSIFICATION_CLASS_ID = ii.CLASSIFICATION_CLASS_ID
LEFT JOIN PWRNXGDTA.LKP_CLASSIFICATION_PBH AS lcp ON lcp.CLASSIFICATION_PBH_ID = ii.CLASSIFICATION_PBH_ID
LEFT JOIN PWRNXGDTA.LKP_CLASSIFICATION_PBHF AS lcpf ON lcpf.CLASSIFICATION_PBHF_ID = ii.CLASSIFICATION_PBHF_ID
LEFT JOIN PWRNXGDTA.LIST_PROPRIETARY_ITEM AS lpi ON lpi.ITEM_IDENTIFIER = ii.ITEM_IDENTIFIER
JOIN PWRNXGDTA.PA_ASSORTMENT AS pa ON pa.PACKAGE_ASSORTMENT_ID = ia.PACKAGE_ASSORTMENT_ID
JOIN PWRNXGDTA.ITEM_PRODUCT AS ip ON ip.ITEM_ID = ii.ITEM_ID
JOIN PWRNXGDTA.PRODUCT_INFO AS pin ON pin.PRODUCT_ID = ip.PRODUCT_ID
LEFT JOIN PWRNXGDTA.PRODUCT_NUTRITIONAL AS pn ON pn.PRODUCT_ID = ip.PRODUCT_ID
LEFT JOIN PWRNXGDTA.LKP_BRAND_INFORMATION AS lbi ON lbi.BRAND_ID = pin.BRAND_ID
AND lbi.RECORD_STATUS = 'A'
JOIN PWRNXGDTA.PACKAGE_IDENTIFIER AS pid ON pid.PACKAGE_ID = pa.PACKAGE_ID
JOIN PWRNXGDTA.PA_CONSUMABLE AS pac ON pac.PACKAGE_ASSORTMENT_ID = pa.PACKAGE_ASSORTMENT_ID
where id.DESCRIPTION_1 like '%HAAGEN DAZ VAN MLK CHO BR%'
GROUP BY ii.ITEM_ID,
ii.PARENT_ITEM_ID,
ii.ITEM_IDENTIFIER,
id.DESCRIPTION_1,
id.DESCRIPTION_4,
pac.PRE_PRICE_AMOUNT
Another way is to use Row_Number to avoid this group by:
Select * from (
SELECT DISTINCT 'Y' AS isEnterprise,
ii.ITEM_ID AS itemId,
ii.PARENT_ITEM_ID as PID,
ii.ITEM_IDENTIFIER AS productNo,
id.DESCRIPTION_1 AS description,
id.DESCRIPTION_4 AS packValue,
pid.PACKAGE_IDENTIFIER AS gtin,
RowN = Row_Number() over (Partition by ii.Item_Id, ii.Parent_Item_id order by pid.PACKAGE_IDENTIFIER) --Added new row_number if you want max you can use desc
pac.PRE_PRICE_AMOUNT AS eachPrice
FROM PWRNXGDTA.ITEM_INFORMATION AS ii
JOIN PWRNXGDTA.ITEM_ASSORTMENT AS ia ON ii.ITEM_ID = ia.ITEM_ID
JOIN PWRNXGDTA.ITEM_DESCRIPTION AS id ON id.ITEM_ID = ii.ITEM_ID
JOIN PWRNXGDTA.BUSINESS_UNIT AS bu ON ii.LOGISTICS_BU_ID = bu.BU_ID
LEFT JOIN PWRNXGDTA.ITEM_EXTN_NONMDM AS ien ON ien.ITEM_IDENTIFIER = ii.ITEM_IDENTIFIER
LEFT JOIN PWRNXGDTA.LKP_CLASSIFICATION_CLASS AS lcc ON lcc.CLASSIFICATION_CLASS_ID = ii.CLASSIFICATION_CLASS_ID
LEFT JOIN PWRNXGDTA.LKP_CLASSIFICATION_PBH AS lcp ON lcp.CLASSIFICATION_PBH_ID = ii.CLASSIFICATION_PBH_ID
LEFT JOIN PWRNXGDTA.LKP_CLASSIFICATION_PBHF AS lcpf ON lcpf.CLASSIFICATION_PBHF_ID = ii.CLASSIFICATION_PBHF_ID
LEFT JOIN PWRNXGDTA.LIST_PROPRIETARY_ITEM AS lpi ON lpi.ITEM_IDENTIFIER = ii.ITEM_IDENTIFIER
JOIN PWRNXGDTA.PA_ASSORTMENT AS pa ON pa.PACKAGE_ASSORTMENT_ID = ia.PACKAGE_ASSORTMENT_ID
JOIN PWRNXGDTA.ITEM_PRODUCT AS ip ON ip.ITEM_ID = ii.ITEM_ID
JOIN PWRNXGDTA.PRODUCT_INFO AS pin ON pin.PRODUCT_ID = ip.PRODUCT_ID
LEFT JOIN PWRNXGDTA.PRODUCT_NUTRITIONAL AS pn ON pn.PRODUCT_ID = ip.PRODUCT_ID
LEFT JOIN PWRNXGDTA.LKP_BRAND_INFORMATION AS lbi ON lbi.BRAND_ID = pin.BRAND_ID
AND lbi.RECORD_STATUS = 'A'
JOIN PWRNXGDTA.PACKAGE_IDENTIFIER AS pid ON pid.PACKAGE_ID = pa.PACKAGE_ID
JOIN PWRNXGDTA.PA_CONSUMABLE AS pac ON pac.PACKAGE_ASSORTMENT_ID = pa.PACKAGE_ASSORTMENT_ID
where id.DESCRIPTION_1 like '%HAAGEN DAZ VAN MLK CHO BR%'
) a
Where a.RowN = 1

How to retrieve count of records in SELECT statement

I am trying to retrieve the right count of records to mitigate an issue I am having. The below query returns 327 records from my database:
SELECT DISTINCT COUNT(at.someid) AS CountOfStudentsInTable FROM tblJobSkillAssessment AS at
INNER JOIN tblJobSkills j ON j.jobskillid = at.skillid
LEFT JOIN tblStudentPersonal sp ON sp.someid2 = at.someid
INNER JOIN tblStudentSchool ss ON ss.monsterid = at.someid
INNER JOIN tblSchools s ON s.schoolid = ss.schoolid
INNER JOIN tblSchoolDistricts sd ON sd.schoolid = s.schoolid
INNER JOIN tblDistricts d ON d.districtid = sd.districtid
INNER JOIN tblCountySchools cs ON cs.schoolid = s.schoolid
INNER JOIN tblCounties cty ON cty.countyid = cs.countyid
INNER JOIN tblRegionUserRegionGroups rurg ON rurg.districtid = d.districtid
INNER JOIN tblGroups g ON g.groupid = rurg.groupid
WHERE ss.graduationyear IN (SELECT Items FROM FN_Split(#gradyears, ',')) AND sp.optin = 'Yes' AND g.groupname = #groupname
Where I run into trouble is trying to reconcile that with the below query. One is for showing just a count of all the particular students the other is showing pertinent information for a set of students as needed but the total needs to be the same and it is not. The below query return 333 students - the reason is because the school the student goes to is in two separate counties and it counts that student twice. I can't figure out how to fix this.
SELECT DISTINCT #TableName AS TableName, d.district AS LocationName, cty.county AS County, COUNT(DISTINCT cc.monsterid) AS CountOfStudents, d.IRN AS IRN FROM tblJobSkillAssessment AS cc
INNER JOIN tblJobSkills AS c ON c.jobskillid = cc.skillid
INNER JOIN tblStudentPersonal sp ON sp.monsterid = cc.monsterid
INNER JOIN tblStudentSchool ss ON ss.monsterid = cc.monsterid
INNER JOIN tblSchools s ON s.schoolid = ss.schoolid
INNER JOIN tblSchoolDistricts sd ON sd.schoolid = s.schoolid
INNER JOIN tblDistricts d ON d.districtid = sd.districtid
INNER JOIN tblCountySchools cs ON cs.schoolid = s.schoolid
INNER JOIN tblCounties cty ON cty.countyid = cs.countyid
INNER JOIN tblRegionUserRegionGroups rurg ON rurg.districtid = d.districtid
INNER JOIN tblGroups g ON g.groupid = rurg.groupid
WHERE ss.graduationyear IN (SELECT Items FROM FN_Split(#gradyears, ',')) AND sp.optin = 'Yes' AND g.groupname = #groupname
GROUP BY cty.county, d.IRN, d.district
ORDER BY LocationName ASC
If you just want the count, then perhaps count(distinct) will solve the problem:
select count(distinct at.someid)
I don't see what at.someid refers to, so perhaps:
select count(distinct cc.monsterid)

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