Data exists and not exists - sql

I have two tables.
Table 1
Claim_id
Claim_Status -- Includes values of "PAID" and "DENIED"
Table 2 - This table contains same claims from Table 1 but with line item details.
Claim_id
Line_number
Status -- Includes values of "PAID" and "DENIED"
A PAID status claim_id from table 1 could have some lines with Status = "DENIED" from table 2
A particular paid claim could have few lines denied in it.
I need to pull number of claims where all lines are in "PAID" status,
and number of claims where some lines are "PAID" and some lines are "DENIED" for a given claim_id.
SELECT x.claim_id, x.claim_status, x.payer_id1
FROM HEADER_CLAIM_TABLE x
WHERE x.payer_id1 = 'company_Z'
AND x.claim_id in (SELECT a.CLAIM_ID,
a.LINE_NUMBER,
a.STATUS,
a.payer_id
FROM LINE_DETAIL_CLAIM_TABLE a
WHERE EXISTS (SELECT b.*
FROM LINE_DETAIL_CLAIM_TABLE B
WHERE b.status = 'DENIED')
AND a.claim_id = b.claim_id
AND a.line_number = b.line_number
AND a.payer_id = b.payer_id)
AND x.claim_status = 'PAID'
I am new to this so please excuse if the above query is totally off course. Please help in getting this data pulled.
Thank you.

Here is some old style sql..try this
select claim_with_no_deny.cnt PAID_COUNT, claim_with_deny.cnt WITH_DENY_COUNT
from
(select count(*) cnt from HEADER_CLAIM_TABLE h where
exists (select 1 from LINE_DETAIL_CLAIM_TABLE D where h.claim_id=d.claim_id and d.status = 'DENIED') claim_with_deny,
(select count(*) cnt from HEADER_CLAIM_TABLE h where
not exists (select 1 from LINE_DETAIL_CLAIM_TABLE D where h.claim_id=d.claim_id and d.status = 'DENIED') claim_with_no_deny

Related

How to update data with multi condition

I have a table with 5 columns like this table below:
I wanna fill the approval column based on conditions such as:
APPROVAL = "Y" IN CASE
(1) CUSTOMER_NEW <> CUSTOMER (as in the case CUSTOMER = 12467)
(2) CUSTOMER_NEW = CUSTOMER AND SALE_SHORT_ID COLUMN HAS DIFFERENT VALUE (as in the case CUSTOMER = 13579)
(3) CUSTOMER_NEW = CUSTOMER AND SALE_SHORT_ID HAS THE SAME VALUE THEN MAX(LEN(SALE_ID) (as in the case CUSTOMER = 65465)
ELSE "N"
My result expected to like this table:
Thanks for your support.
I am not sure about all your your conditions but this one could do it:
UPDATE a
SET approval =
CASE WHEN
a.customer <> a.customer_new OR
a.customer = a.customer_new AND b.sale_short_eq = 0 OR
a.customer = a.customer_new AND a.sale_id = b.max_len_sale_id
THEN 'Y'
ELSE 'N'
END
FROM
thetable a
INNER JOIN (
SELECT
customer,
CASE WHEN MIN(sale_short_id) = MAX(sale_short_id) THEN 1 ELSE 0 END AS sale_short_eq,
( SELECT TOP 1 sale_id
FROM thetable
WHERE customer = c.customer
ORDER BY LEN(sale_id) DESC
) AS max_len_sale_id
FROM thetable c
GROUP BY customer
) b
ON a.customer = b.customer
Note that the columns b.sale_short_eq and b.max_len_sale_id are returned by a sub-query joined to the main query.
Especially SALE_SHORT_ID HAS THE SAME VALUE THEN MAX(LEN(SALE_ID) is not clear. Did you mean that SALE_ID must be the same as the maximum length SALE_ID? Because SALE_SHORT_ID cannot be the same than any SALE_ID. And what happens if two different SALE_IDs have the same max length?
See: https://dbfiddle.uk/7Ct87-Mk

How do I update a column on a table where duplicate records are found

I have this sql script that selects duplicate record . i want to convert it to an update statement where it updates are particular column called STATUS in the table with the string "Duplicated"
Dbms is Oracle
Select * From (
select * from VisaNnsMainTable
Where TRN_TYPE = '500' OR TRN_TYPE = '2500') A
inner join (
select ARN,WAN_NUM, ABS(TRN_AMOUNT) AS AMOUNT
from VisaNnsMainTable
Where TRN_TYPE = '500' OR TRN_TYPE = '2500'
group by ARN, WAN_NUM,ABS(TRN_AMOUNT)
having count(*) > 1
) B on A.ARN = B.ARN
and A.WAN_NUM = B.WAN_NUM
and ABS(A.TRN_AMOUNT) = B.AMOUNT
ORDER BY A.WAN_NUM
Please help me review this I think it does what I want ,but I am not sure if i wrote it well
UPDATE VisaNnsMainTable
SET EXCEPTION = 'Duplicate'
where CONCAT(ARN,WAN_NUM,ABS(TRN_AMOUNT)) in
( select CONCAT(ARN,WAN_NUM,ABS(TRN_AMOUNT))
from VisaNnsMainTable
group by CONCAT(ARN,WAN_NUM,ABS(TRN_AMOUNT))
having count(*) > 1 ) AND (TRN_TYPE = '500' OR TRN_TYPE = '2500')

HIVESQL Query Where Statement Assistance

I have a query that I am pulling transactions from. I want to be able to pull transactions where my commodity field = A1 and the newvalue field <> A1 for any of the transactions for each individual case number. In other words, I have 2 case numbers with 5 transactions each, one case number has a transaction record of commodity = A1 and newvalue = A1. The other case has a record where commodity = A1 and newvalue= B2, this is the case I would like returned in the query. Keep in mind that the previous case may have that same transaction but it should not be returned because there is a record of newvalue = A1. I have attached an image and the records highlighted in yellow are what I expect my output to be. Below is my current "Where" statement that I need help re-writing. I was also told that I may need a "Group BY" statement which I tried and still pulled the same results.
SELECT
Allcases.caseno as caseno, Allcases.division_desc as division_desc, Allcases.close_date as close_date, Allcases.week_of as week_of,
Allcases.case_type as case_type,
a.transactdate as transactdate, a.transacttypeid as transacttypeid, a.userid as userid,
concat(RTRIM(Usr.fullname), ' <', RTRIM(Usr.EmailAddress), '>') as CR1_CR2_FULLNAME,
Allcases.commodity as commodity,
b.oldvalue as oldvalue, b.newvalue as newvalue, changereason as changereason
FROM
(
select b.*, sum(case when b.newvalue = 'A1' then 1 else 0 end) over(partition by Allcases.caseno) cnt_new_value_A1
from
dataiku.qca_casedatachange_parquet b
INNER JOIN dataiku.qcatransact_parquet a
ON b.transactid = a.transactid
INNER JOIN dataiku.qca_validated_cases_consolidated_parquet Allcases
ON a.casedataid = Allcases.casedataid
INNER JOIN dataiku.set_qca_reclassification_head_parquet h
ON Allcases.caseno = h.caseno
INNER JOIN dataiku.qca_user_parquet Usr
ON a.UserID = Usr.UserID
where
b.FieldID = 6
AND a.transacttypeid IN (1, 2, 3)
AND Allcases.commodity = 'A1'
)s
where cnt_new_value_A1 = 0
ORDER BY Allcases.caseno, A.transactid
If you do not want to return cases for which does not exists record with b.newvalue = 'A1' then calculate analytic sum() and use it in the where
select ...
from
(
select t.*,
sum(case when newvalue ='A1' then 1 else 0 end) over(partition by case_number) cnt_new_value_A1
from ...
where
FieldID = 6 --COMMODITY
AND transacttypeid IN (1, 2, 3)
AND commodity = 'A1'
)s
where cnt_new_value_A1 = 0 --No A1 in newvalue per case_number

How to get fields from multiple tables

I want to get fields from 2 different tables . The last field candidate_score_id has a many to one relationship. So how should I join the below 2 queries
1) To get candidate_score_id from the candidate_score table.
select candidate_score_id from candidate_score a where
a.assessment_id = NEW.assessment_id and
a.candidate_id = NEW.candidate_id and
a.attempt_Count = NEW.attempt_count;
2) To insert different fields in to the candidate_score_details table. The field in this table should be obtained by query above.
insert into candidate_score_details(candidate_score_details_id, candidate_id, assessment_id, attempt_count, score_type, score_tag,correct, candidate_score_id)
select uuid();
select a.candidate_id, a.assessment_id,a.attempt_count,"BY-COMPLEXITY",
case c.complexity
when 1 then "HIGH"
when 2 then "MEDIUM"
when 3 then "LOW"
end, count(*) from candidate_answer a, answer_key b, question_meta_data c where a.candidate_id = NEW.candidate_id and
a.assessment_id = NEW.assessment_id and
a.attempt_count = NEW.attempt_count and
a.assessment_id = b.assessment_id and
a.question_id = b.question_number and
a.response = b.answer and
a.question_id = c.question_number
group by a.candidate_id, a.assessment_id, a.attempt_count, c.complexity;
Just looking at the SQL joining aspect of your question, you'll need to specify the table I THINK you're aliasing a 2nd table with the "NEW" reference. If that's the case, then the query would be (replacing "OTHER_TABLE_NAME" with the name of the 2nd table:
select a.candidate_score_id
from candidate_score a
left join OTHER_TABLE_NAME new on
and a.assessment_id = NEW.assessment_id
and a.candidate_id = NEW.candidate_id
and a.attempt_Count = NEW.attempt_count
Seems that Query 1 has the same 3 criteria on the "candidate_score" table as for the "candidate_answer" table in Query 2.
So how about adding a LEFT JOIN of "candidate_score" to "candidate_answer" on those 3 fields?
For example:
INSERT INTO candidate_score_details
(
candidate_score_details_id,
candidate_id,
assessment_id,
attempt_count,
score_type,
score_tag,
correct,
candidate_score_id
)
SELECT
uuid(),
answer.candidate_id,
answer.assessment_id,
answer.attempt_count,
'BY-COMPLEXITY' AS score_type,
(CASE meta.complexity
WHEN 1 THEN 'HIGH'
WHEN 2 THEN 'MEDIUM'
WHEN 3 THEN 'LOW'
END) AS score_tag,
COUNT(*) AS correct,
MAX(score.candidate_score_id) AS max_candidate_score_id
FROM candidate_answer AS answer
JOIN answer_key AS akey
ON (akey.assessment_id = answer.assessment_id AND akey.question_number = answer.question_id AND akey.answer = answer.response)
LEFT JOIN candidate_score AS score
ON (score.candidate_id = answer.candidate_id AND score.assessment_id = answer.assessment_id AND score.attempt_count = answer.attempt_count)
LEFT JOIN question_meta_data AS meta
ON meta.question_number = answer.question_id
WHERE answer.candidate_id = NEW.candidate_id
AND answer.assessment_id = NEW.assessment_id
AND answer.attempt_count = NEW.attempt_count
GROUP BY answer.candidate_id, answer.assessment_id, answer.attempt_count, meta.complexity;

SQL - How to find entries where a value is missing between two rows

We are using Presto SQL at my job. I have spent hours trying to search for the answer to this question but can't find an answer and it's quite difficult to search for. Solving this issue opens the door to fixing a lot of problems.
I need to write a query that tries to find all entries where REQUEST_CANCEL & CHARGED exist but CANCEL_ACCOUNT is missing.
CHARGED & CANCEL_ACCOUNT should always come after REQUEST_CANCEL.
Table Name: CUSTOMER_INFO
|DATE_TIME|CUST_ID |ACTION |
|20180726 |1234 |CHARGED |
|20180726 |1234 |CANCEL_ACCOUNT|
|20180726 |1234 |REQUEST_CANCEL|
All these values exist in the same table. Here's what I have so far.
SELECT *
FROM
(SELECT *
FROM CUSTOMER_INFO
WHERE
DATE_TIME = 20180726
AND ACTION = REQUEST_CANCEL) as a
JOIN
(SELECT *
FROM CUSTOMER_INFO
WHERE
DATE_TIME = 20180726
AND ACTION = CHARGED) as b
ON a.CUST_ID = b.CUST_ID
WHERE
a.TIME < b.TIME
Let me explain it in a way that makes sense.
A = REQUEST_CANCEL
B = CANCEL_ACCOUNT
C = CHARGED
How do you query for when A and C exist but B is missing. The sequence needs to be exact A > B > C. It's essentially querying for something that doesn't exist between two values that do exist. In my current query, B can be returned between the two values and that's NOT what I want.
I think you're searching for NOT EXISTS and a corellated subquery.
SELECT *
FROM (SELECT *
FROM customer_info
WHERE action = 'REQUEST_CANCEL') rc
INNER JOIN (SELECT *
FROM customer_info
WHERE action = 'CHARGED') c
ON c.cust_id = rc.cust_id
AND c.date_time >= rc.date_time
WHERE NOT EXISTS (SELECT *
FROM customer_info ca
WHERE ca.cust_id = rc.cust_id
AND ca.action = 'CANCEL_ACCOUNT'
AND ca.date_time >= rc.date_time
AND ca.date_time <= c.date_time);
Use group by and having:
select cust_id
from customer_info ci
where date_time = 20180726 and
action in ('REQUEST_CANCEL', 'CHARGED', 'CANCEL_ACCOUNT')
group by cust_id
having sum(case when action = 'REQUEST_CANCEL' then 1 else 0 end) > 0 and
sum(case when action = 'CHARGED' then 1 else 0 end) > 0 and
sum(case when action = 'CANCEL_ACCOUNT' then 1 else 0 end) = 0 ;
Each sum() counts the number of matching records for the customer with that action. The > 0 says that one exists. The = 0 says that none exist.
The database doesn't matter for this logic. Here is a SQL Fiddle using MySQL.