Test Case for Triple Join in SQL - sql

SELECT triple_join('A multiple join on the Equipment, EquipmentTypes, and
RentalInfo works effectively: ',
CASE WHEN
(SELECT name, e.riid, rental_start, in_use FROM Equipment AS e JOIN
EquipmentTypes ON equipment_type = etid JOIN RentalInfo AS ri ON
e.riid = ri.riid)
= ('Enabler 420', 1, '20141107', 1)
THEN 'Passed' ELSE 'Failed' END
);
This is the code that tests whether my join is working effectively. When I run the code, however, it says I have a syntax error near ",". Can someone tell me what's going on?
P.S.: The Equipment, EquipmentTypes, and RentalInfo are tables I have defined and 'inserted to' in another file.

Not sure if it solves the problem, but it is much simpler to debug than what you had. Also, it will solve the problem of multiple matching records:
SELECT triple_join('A multiple join on the Equipment, EquipmentTypes, and
RentalInfo works effectively: ',
CASE WHEN EXISTS (
SELECT TOP 1 1 FROM Equipment AS e
INNER JOIN EquipmentTypes as et ON e.equipment_type = et.etid
INNER JOIN RentalInfo AS ri ON e.riid = ri.riid
WHERE name = 'Enabler 420' and e.riid = 1 and
rental_start = '20141107' and in_use = 1)
THEN 'Passed' ELSE 'Failed' END
);
If problem still persist try to run separately internal "SELECT" and the function and see what is causing the problem.

Related

Case When + IN combination

I'm a bit stuck in my coding here... I have this extense and complex code, but I'm actually failling by the end of it. I'm getting the SQL Error [42804]: ERROR: argument of CASE/WHEN must be type boolean, not type character varying
The thing, is: when "bairro" matches a row from "SUB_COUNTRY_DB", get psd.name, else get z.name. Any tips on how I could accomplish this?
select distinct
aa.mes,
--aa.modalidade,
--to_date(aa.created_date, 'yyyy-mm-dd') data_captacao,
ucl.ja_comprou_lf as comprou_lf,
case when bairro in (select sub_country from sub_country_DB)
then psd.name
else z.name
end loja,
count (distinct aa.customer_uid) qtde_socios,
count (distinct aa.assinatura_uid) qtde_assinaturas
from assinaturas_ativas aa
left join ultima_compra_loja_fisica ucl on (aa.customer_uid = ucl.customer_uid
and aa.mes = ucl.mes)
left join zip_code z on (aa.customer_uid = z.customer_uid
and aa.mes = z.mes)
left join SUB_COUNTRY_DB psd
on (psd.district = aa.bairro)
group by 1,2,3--,4
Try variants like:
moving condition to an inner query
CASE WHEN EXISTS (SELECT DISTINCT sub_country FROM sub_country_DB WHERE sub_country = barrio)
ANY (PostgreSQL only)
CASE WHEN bairro = ANY(ARRAY_AGG(select sub_country from sub_country_DB))

select only one value in 1:N relation

i want to have only one value in the result of the query which is the first value, or the last value, i tried many things but i coudnt resolve it, the query is too long but i picked for you only the part where i am stucked.
select eccev.extra_data , c.id,
case when (eccev.extra_data::json->'tns')::VARCHAR = 'false'
then 'NON'
else case when coalesce((eccev.extra_data::json->'tns')::VARCHAR, '') = '' then 'EMPTY VALUE' else 'OUI'
end end as tns
from endorsement_contract_covered_element_version eccev, endorsement_contract_covered_element ecce, endorsement_contract ec, contract c, endorsement e, party_party pp
WHERE ec.endorsement = e.id
and e.applicant = pp.id
and c.subscriber = pp.id
AND eccev.covered_element_endorsement = ecce.id
and ecce.contract_endorsement = ec.id
and c.contract_number = 'CT20200909112'
with this query i have the result
{"qualite":"non_etu","tns":false} 199479 NON
{"qualite":"non_etu","tns":false} 199479 NON
{"qualite":"non_etu","tns":false} 199479 NON
i want to have only the first or the last row so i dont have repetition on the other rows, i saw that we can use first_value(X over (XX)) but i couldnt make it.
if u guys can help me, i would be gratefull
Thanks
you can try this
select distinct on (eccev.extra_data , c.id) eccev.extra_data , c.id, case when ...
but your query seems not optimized as you cross join 6 tables all together ...

Making a case statement when a count condition is bigger than 0

I want to make a pretty complex SQL query, which results in 0/1 or TRUE/FALSE depending on my conditions.
Idea is that I have a customer table, and then I want to make a couple of checks in different tables, and then if either is true, then we return TRUE, and if not, FALSE:
I was thinking to do this with CASE. See example below:
select
case
((select count(*) from boughtleads bl where bl.customerid = cu.id)>0)
then 'TRUE'
else 'FALSE'
end
from customers cu
left join leadagents la on la.customerid = cu.id
where cu.vatnumber = '30218124'
This returns:
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near '>'.
My challenge is then. First of all, the above query fails for some reason, my other problem is I can't use an OR.
My ideal pseudocode would be something like:
select
case
(
((select count(*) from boughtleads bl where bl.customerid = cu.id)>0)
OR
((select count(*) from leadnotifications ln where ln.leadagentid = la.id)>))
then 'TRUE'
else 'FALSE'
end
from customers cu
left join leadagents la on la.customerid = cu.id
where cu.vatnumber = '30218124'
Any ideas on how to attack this?
You are missing when:
select (case when (select count(*) from boughtleads bl where bl.customerid = cu.id) > 0
then 'TRUE'
else 'FALSE'
end)
from customers cu left join
leadagents la
on la.customerid = cu.id
where cu.vatnumber = '30218124';
That said, from a performance perspective it is better to write such conditions using exists:
select (case when exists (select 1 from boughtleads bl where bl.customerid = cu.id)
then 'TRUE'
else 'FALSE'
end)
from customers cu left join
leadagents la
on la.customerid = cu.id
where cu.vatnumber = '30218124'
The count(*) version has to find all matching rows in boughtleads. The exists version can stop at the first match.

Joining a derived table postgres

I have 4 tables:
Competencies: a list of obviously competencies, static and a library
Competency Levels: refers to an associated group of competencies and has a number of competencies I am testing for
call_competency: a list of all 'calls' that have recorded the specified competency
competency_review_status: proving whether each call_competency was reviewed
Now I am trying to write this query to count a total and spit out the competency, id and whether a user has reached the limit. Everything works except for when I add the user. I am not sure what I am doing wrong, once I limit call competency by user in the where clause, I get a small subset that ONLY exists in call_competency returned when I want the entire list of competencies.
The competencies not reached should be false, ones recorded appropriate number true. A FULL list from the competency table.
I added the derived table, not sure if this is right, obviously it doesn't run properly, not sure what I'm doing wrong and I'm wasting time. Any help much appreciated.
SELECT comp.id, comp.shortname, comp.description,
CASE WHEN sum(CASE WHEN crs.grade = 'Pass' THEN 1 ELSE CASE WHEN crs.grade = 'Fail' THEN -1 ELSE 0 END END) >= comp_l.competency_break_level
THEN TRUE ELSE FALSE END
FROM competencies comp
INNER JOIN competency_levels comp_l ON comp_l.competency_group = comp.competency_group
LEFT OUTER JOIN (
SELECT competency_id
FROM call_competency
WHERE call_competency.user_id IN (
SELECT users.id FROM users WHERE email= _studentemail
)
) call_c ON call_c.competency_id = comp.id
LEFT OUTER JOIN competency_review_status crs ON crs.id = call_competency.review_status_id
GROUP BY comp.id, comp.shortname, comp.description, comp_l.competency_break_level
ORDER BY comp.id;
(Shooting from the hip, no installation to test)
It looks like the below should do the trick. You apparently had some of the joins mixed up, with a column from a relation that was not referenced. Also, the CASE statement in the main query could be much cleaner.
SELECT comp.id, comp.shortname, comp.description,
(sum(CASE WHEN crs.grade = 'Pass' THEN 1 WHEN crs.grade = 'Fail' THEN -1 ELSE 0 END) >= comp_l.competency_break_level) AS reached_limit
FROM competencies comp
JOIN competency_levels comp_l USING (competency_group)
LEFT JOIN (
SELECT competency_id, review_status_id
FROM call_competency
JOIN users ON id = user_id
WHERE email = _studentemail
) call_c ON call_c.competency_id = comp.id
LEFT JOIN competency_review_status crs ON crs.id = call_c.review_status_id
GROUP BY comp.id, comp.shortname, comp.description
ORDER BY comp.id;

Want to filter SQL Server query

Currently I am pulling out the Facilities where the permitType is 'Hazardous waste' and the licenseStatus is 'Open', but there will be cases where the facilities will have more than one permit type suppose a facility can have two permit types
Hazardous waste (status - OPEN)
AST (OPEN)
so I should not display this facility in my output if it other permit types (Status - OPEN) apart from the 'hazardous waste', but if the other permit type has status - CLOSE then my query should output the Facility i.e if AST(Status - CLOSE) then the facility should be pulled from the database.
I wrote the following query but not sure where to include the condition.
SELECT
e.facilityID
,f.organization_core AS 'Facility Name'
,f.address_full_core AS 'Facility Address'
,a.permitNumber AS 'Permit Number'
,b.permitName AS 'Permit Name'
,a.licenseStatus AS 'Permit Status'
,c.permitType AS 'Permit Type'
FROM
tblPermits a
LEFT JOIN
dbo.tblPermit_Names b ON a.permitID = b.permitID
LEFT JOIN
dbo.tblLKP_Permit_Facilities d ON a.permitID = d.permitID
LEFT JOIN
dbo.tblPermit_Types c ON a.permitTypeID = c.permitTypeID
LEFT JOIN
dbo.tblFacility e ON d.facilityID = e.facilityID
LEFT JOIN
dbo.tblAddresses f ON e.facilityAddressID = f.addressID
WHERE
a.permitTypeID IN (SELECT permitTypeID
FROM dbo.tblPermit_Types
WHERE permitType IN ('Hazardous Waste'))
AND a.licenseStatus = 'Open'
AND isNull(a.deleted, 0) = 0
I think the following query implements your rules. The idea is to focus on the facility and not on all the extra stuff in the tables that you have put in. You need to aggregate by facilityid so you can apply logic to all the permits issued for each one:
SELECT f.facilityID
FROM dbo.tblFacility f join
dbo.tblLKP_Permit_Facilities pf
on pf.facilityID = f.facilityId join
tblPermits p
on pf.permitID = p.permitID join
dbo.tblPermit_Types pt
ON pt.permitTypeID = p.permitTypeID
GROUP BY f.facilityID
HAVING SUM(case when pt.permitType IN ('Hazardous Waste') and p.licenseStatus = 'Open'
then 1 else 0
end) > 0 and
SUM(case when pt.permitType NOT IN ('Hazardous Waste') and p.licenseStatus = 'Close'
then 1 else 0
end) > 0;
Each condition in the having clause is applying one of your rules.
I'm a little confused as to your table structure, but this is what I think you should do.
Your where statement should be id in (Select id from table where status = open and count(id) = 1 group by facility)
AND Type in ('Hazardous Waste')
The first part of the where statement will limit all ids to those that are open with only one open type per facility, the second part limits it to just hazardous waste.
If you have a facility with 10 permits, but only one is active, it will pull it into the list, but if the active permit isn't hazardous waste, it will then exclude it.
Sorry I can't give you exact code.
Also, nix as many of those outer joins as you can. Inner joins are faster, and are more likely to represent the data you want.