SQL Sylob return a boolean - sql

I am currently discovering the Sylob 5 ERP and I would like some help on one of my queries because the Sylob support is overwhelmed with demands.
I would like my query to display if one of the operations in my fabrication order is late.
I already have a query that displays every operations and if it's late or not:
SELECT
distinct
ordreFabrication.codeOF as Code_OF,
operationOrdreFabrication.libelle as Libelle,
operationOrdreFabrication.centreCharge.libelle || ' (' ||
operationOrdreFabrication.centreCharge.code || ')' as Centre_charge,
operationOrdreFabrication.dateDebutPrevue as Début_prévu,
(
CASE
WHEN current_date() > operationOrdreFabrication.dateDebutPrevue and
operationOrdreFabrication.etatAvancementOperationOF = '0' THEN ('<div style=''color:red''>' ||
'Retard sur le début' || ' </div>')
WHEN current_date() > operationOrdreFabrication.dateFinPrevue and
operationOrdreFabrication.etatAvancementOperationOF != '2' THEN ('<div style=''color:red''>' ||
'Retard sur la fin' || ' </div>')
ELSE ('Aucun retard')
END
) as Retard,
operationOrdreFabrication.dateDebutReelle as Début_Réel,
operationOrdreFabrication.dateFinPrevue as Fin_prévue
FROM
OperationOrdreFabricationEntite as operationOrdreFabrication
left outer join operationOrdreFabrication.ordreFabrication as ordreFabrication
WHERE
operationOrdreFabrication.id not like 'DefaultRecord_%'
AND
operationOrdreFabrication.dateFinValidite is null
AND
ordreFabrication.dateFinValidite is null
AND
operationOrdreFabrication.sousTraitance in ('false')
AND
((current_date() > operationOrdreFabrication.dateDebutPrevue and
operationOrdreFabrication.etatAvancementOperationOF = '0'
) OR (current_date() > operationOrdreFabrication.dateFinPrevue and
operationOrdreFabrication.etatAvancementOperationOF != '2'))
ORDER BY
1 asc
But I want this to return true or false when my case returns anything else than "Aucun retard"
so I can use it as a subquery

Looks like you want EXISTS (NOT EXISTS)
select exists(
select 1
from (
--you original query
) t
where retard = 'Aucun retard') flag

Related

How can I add a value to the beginning of a column for a select list without changing the column in the table?

select display_value from (
select
FIRST_NAME || ' ' || LAST_NAME as display_value,
case
when display_value is null then '<Not Assigned>'
end,
UPPER(Number) as return_value,
1 as ord
from team_members
where
Number is not NULL
and ANSWER = 'Y')
union all (
select
'Not Required' as display_value,
'Not Required' as return_value,
0 as ord
from dual
) order by ord, display_value;
The expected output should be:
Not Assigned (if null)
Not Required
List of Names
This will be used for a select list with a save button which will update the table based on the selected value.
Any ideas?
Thanks #mathguy this is the answer I came up with and it works.
SELECT T1.display_value
FROM (
(
SELECT tm.first_name || ' ' || tm.last_name as display_value,
UPPER(tm.number) as return_value,
1 as ord
FROM team_members tm
WHERE tm.number IS NOT null
AND tm.bool = 'Y')
UNION ALL (
SELECT 'Not Required' as display_value,
'Not Required' as return_value,
0 as ord
FROM dual)
ORDER BY ord, display_value) T1
The software has a built in function to display a null value, so I didn't have to make a case for null values in the first place.

Postgres 9.1's concat_ws equivalent in Amazon redshift

I've got a query originally written for pg9.1 that I'm trying to fix for use on redshift as follows
select concat_ws(' | ', p.gb_id, p.aro_id, p.gb_name) c from (
select ca.p_id,
avg(ca.ab) as ab
from public.fca
join temp_s_ids s on ca.s_id = s.s_id
group by ca.p_id
) as x
join public.dim_protein as p on x.protein_id = p.protein_id;";
I've been trying to test it out on my own, but as it is created from temporary tables that are created by a php session, I haven't had any luck yet. However, my guess is that the concat_ws function isn't working as expected in redshift.
I don't believe there is an equivalent in redshift. You will have to roll your own. If there are no NULLS you can just use the concatenation operator ||:
SELECT p.gb_id || ' | ' || p.aro_id || ' | ' || p.gb_name c
FROM...
If you have to worry about nulls (and its separator):
SELECT CASE WHEN p.gb_id IS NOT NULL THEN p.gb_id || ' | ' END || CASE WHEN p.aro_id IS NOT NULL THEN p.aro_id || ' | ' END || COALESCE(p.gb_name, '') c
FROM
Perhaps that can be simplified, but I believe it will do the trick.
To handle NULLs, you can do:
select trim('|' from
coalesce('|' || p.gb_id) ||
coalesce('|' || p.p.aro_id) ||
coalesce('|' || p.gb_name)
)
from . . .

Oracle query to check for failure more than 90 %

I have a situation where I need to write a monitoring query to run every 2 hour to raise alert when processed count becomes less than 90%.
Lets say we have a Table Incoming Message where all incoming messages are captured and another table where all processed messages are captured.
This is what I came up with, this works but I am wondering if there is better way of doing this?
SELECT (CASE WHEN PROCESSEDCOUNT <= INCOMINGCOUNT * .9
THEN 'ALERT:: Process Count ' || PROCESSEDCOUNT || ' is less than 90% of Incoming count ' || INCOMINGCOUNT || '. '
ELSE 'FINE:: Process Count ' || PROCESSEDCOUNT || ' is more than or equal to 90% of Incoming count ' || INCOMINGCOUNT || '. '
END ) as Status
from
(SELECT
(SELECT COUNT(*)
FROM INCOMING_TABLE D WHERE INSERTION_TIME > SYSDATE - (1/12)
AND EXISTS (SELECT * FROM PROCESSED_TABLE C WHERE ( D.MESSAGE_ID = C.MESSAGE_ID)
AND C.PROCESSED_TIME > SYSDATE- (1/12))) AS PROCESSEDCOUNT,
(SELECT COUNT(*) FROM INCOMING_TABLE WHERE INSERTION_TIME > SYSDATE - (1/12)) AS INCOMINGCOUNT
FROM DUAL);
PROCESSED_TABLE used for storing other records as well, that is the
reason I need to use EXISTS to figure out process count.
I understand as time captured in two tables may not fall into same
time duration. We are not worried about that right now, just want to
make sure majority of records processed.
We are using oracle 11g, if that helps.
You are querying the same data from INCOMING_TABLE twice, which isn't really efficient ;-)
One possibility could be to outer join:
SELECT
CASE
WHEN COUNT(C.MESSAGE_ID) <= COUNT(*) * .9
THEN 'ALERT:: Process Count ' || COUNT(C.MESSAGE_ID) || ' is less than 90% of Incoming count ' || COUNT(*) || '. '
ELSE 'FINE:: Process Count ' || COUNT(C.MESSAGE_ID) || ' is more than or equal to 90% of Incoming count ' || COUNT(*) || '. '
END as Status
FROM INCOMING_TABLE D
LEFT OUTER JOIN PROCESSED_TABLE C
ON C.MESSAGE_ID = D.MESSAGE_ID
AND C.PROCESSED_TIME > SYSDATE- (1/12)
WHERE D.INSERTION_TIME > SYSDATE - (1/12)
/
That will work if you can be sure either zero or one record exists in PROCESSED_TABLE for each message_id. Maybe you can add a AND C.PROCESS_TYPE = ... or something to make that condition come true.
If you cannot guarantee that a join to PROCESSED_TABLE returns at most one row, you can move your EXISTS to inside a COUNT instead of the WHERE clause and thereby again avoid accessing INCOMING_TABLE twice:
SELECT (CASE WHEN PROCESSEDCOUNT <= INCOMINGCOUNT * .9
THEN 'ALERT:: Process Count ' || PROCESSEDCOUNT || ' is less than 90% of Incoming count ' || INCOMINGCOUNT || '. '
ELSE 'FINE:: Process Count ' || PROCESSEDCOUNT || ' is more than or equal to 90% of Incoming count ' || INCOMINGCOUNT || '. '
END ) as Status
from
(
SELECT COUNT(*) INCOMINGCOUNT
, COUNT(
CASE
WHEN EXISTS (SELECT * FROM PROCESSED_TABLE C
WHERE D.MESSAGE_ID = C.MESSAGE_ID
AND C.PROCESSED_TIME > SYSDATE- (1/12))
THEN 1
END
) PROCESSEDCOUNT
FROM INCOMING_TABLE D
WHERE D.INSERTION_TIME > SYSDATE - (1/12)
)
/
(PS. If you are at the start of writing a lot of code to handle a messaging queue, I would also suggest like #DARK_A to look into Advanced Queues instead of building your own. There is a lot of issues you need to handle in a messaging system, so why have that trouble if you can use what Oracle has already built ;-)

Oracle-sql : Query with hiererchical group by

I have a table like:
ID || Ent NAME || FUNCTION
1 || Dupuis || Signatory
1 || Daturt || Decision Maker
1 || Nobel || (Null )
2 || Karl || Decision Maker
2 || Titi || (Null )
3 || Cloves || (Null )
3 || Cardigan || (Null )
I want to get the most "important" people in a pre -established hierarchy (Signatory > Decision Maker > (Null ) )
So the expected result is:
ID Ent || NAME || FUNCTION
1 || Dupuis || Signatory
2 || Karl || Decision Maker
3 || Cardigan || (Null )
for the 3rd , i don't care of person selected .
I work in Oracle with extremely limited right , I can do that SELECT ( and this it is s*** ).
I have a solution bypass but it is extremely ugly and I am not satisfied:
(SELECT "ID Ent" max (NOM), max (FUNCTION)
FROM table
WHERE FUNCTION = 'Signatory' GROUP BY "ID Ent")
UNION
(SELECT "ID Ent" max (NOM), max (FUNCTION)
FROM table
WHERE FUNCTION = 'Decision Maker'
AND "ID Ent" not in (SELECT "ID Ent" FROM table WHERE FUNCTION = 'Signatory')
GROUP BY "ID Ent")
UNION
(SELECT "ID Ent" max (NOM), max (FUNCTION)
FROM table
WHERE FUNCTION = 'Decision Maker'
AND "ID Ent" not in (SELECT "ID Ent" in FUNCTION FROM table WHERE ('Signatory', 'Decision Maker'))
GROUP BY "ID Ent");
Do you have a better way to do this?
I would approach this using analytic functions:
select t.Id, t.Name, t.Function
from (select t.*,
row_number() over (partition by id
order by (case when function = 'Signatory' then 1
when function = 'Decision Maker' then 2
else 3
end)
) as seqnum
from table t
) t
where seqnum = 1;

ORA-00905: missing keyword error in case after where clause

I have the following query which is giving error ORA-00905: missing keyword. I've not been able to find the syntax despite continuous efforts for last few hours. Please help.
SELECT a.DOCUMENT_CATEGORY,
a.template_id,
a.category_id,
a.REVIEW_CATEGORY,
a.WITH_BIDS,
a.WITH_FINAL_DOCUMENTS,
b.divn_id,
b.deptt_id,
a.vdr_id,
C.DEPARTMENT,
a.TEMPLATE_TITLE
FROM DCTM_VDR_REF_DTLS a, DCTM_VDR_REF_MASTER b, VW_DIVN_DIR c
WHERE b.DIVN_ID = c.DIVN_CODE
AND b.DEPTT_ID = c.SECTN_CODE
AND a.vdr_id = b.vdr_id
AND (b.REFERENCE_NUMBER, b.APPROVED_ON) IN
( SELECT MAX (REFERENCE_NUMBER), MAX (APPROVED_ON)
FROM DCTM_VDR_REF_MASTER
WHERE REFERENCE_NUMBER =
(SELECT DISTINCT
NVL (TRIM (MR_NUMBER), TRIM (TENDER_NO))
FROM EILEDMS.EIL_DOCUMENT_SV#EDMS_DBLINK
WHERE object_name =
'A307-0IC-JA-MR-7960-1030-157-FOA'
AND r_object_type =
'eil_foa_order_pr_doc'
AND ( title = 'FOA'
OR title = 'DRAFT FOA'))
AND APPROVED_ON IS NOT NULL
GROUP BY DIVN_ID, DEPTT_ID)
AND REVIEW_CATEGORY <> 'Delete Category'
AND (CASE (SELECT IS_SCHEDULE_LOCKED
FROM DCTM_VENDOR_SCHEDULE
WHERE SCH_ID = 359)
WHEN 0
THEN
1
WHEN 1
THEN
(a.template_id || '-' || a.category_id) IN
(SELECT template_id || '-' || category_id
FROM DCTM_VENDOR_SCH_UNLOCK_DTLS
WHERE APPROVAL = 'Y'
AND APPROVAL_UPTO >= SYSDATE
AND CONSUMED = 0
AND sch_ID = 359)
END) = 1
ORDER BY c.DEPARTMENT ASC,
a.TEMPLATE_ID,
a.SORT_ORDER,
a.DOCUMENT_CATEGORY ASC
Can't we use IN clause inside a THEN statement?
Now that you've edited your question, it looks like you are simply trying to look up category_id and template_id in DCTM_VENDOR_SCH_UNLOCK_DTLS. Does the following work for you?
then
(
SELECT COUNT(*) -- 1 if found, 0 otherwise
FROM DCTM_VENDOR_SCH_UNLOCK_DTLS
WHERE APPROVAL = 'Y'
AND APPROVAL_UPTO >= SYSDATE
AND CONSUMED = 0
AND sch_ID = 359
AND template_id = a.template_id
AND category_id = a.category_id
AND rownum = 1
)
This is not actually about an IN clause after WHERE being allowed or not. The expression
a.category_id IN (SELECT ...)
evaluates to TRUE or FALSE. Your statement
a.template_id || '-' || a.category_id IN (SELECT ...)
tries to concatenate that TRUE or FALSE with a.template_id and a minus sign. This is not possible, as there is no boolean type in Oracle SQL. Think it over what you actually want to concatenate.
EDIT: Now that you set parentheses, you compare a string with another string resulting from a select statement. Fine so far. But still: All this evaluates to a boolean, not a number. Your first then results in a number (1), your second in a boolean (TRUE or FALSE). Oracle SQL has no boolean type, so your expression makes no sense to the parser and you get a syntax error.