find unmatched data - sql

column Role _id has13 and 22 as there id, need to fetch the unmatched ID from column cmat_customer_id.
see below data for reference"
SYSTEM_SERIAL_NUMBER ROLE_ID TOTAL_ROLE_ID CMAT_CUSTOMER_ID CMAT_SITE_ID
200000301498 13 1 6082581 -999999
200000304907 13 1 5018171 -999999
200000273689 13 1 5008520 -999999
200000280436 13 1 5008520 -999999
451507000097 22 1 5013865 -999999
451448000036 13 1 5008621 5008622
451507000148 22 1 5013459 -999999
FB6500N120181 13 1 5002239 6019184
FB6500N120181 22 1 5002239 6019184
451507000097 22 1 5013865 5013867
451507000097 13 1 5013865 -999999
Expected resulet
SYSTEM_SERIAL_NUMBER ROLE_ID count_ROLE_ID CMAT_CUSTOMER_ID CMAT_SITE_ID
200000301498 13 1 6082581 -999999
200000301498 22 1 5018171 -999999
200000304907 13 1 5018172 -999999
200000304907 22 1 5008520 -999999
451507000148 13 1 5008512 -999999
we do not want below result set
SYSTEM_SERIAL_NUMBER ROLE_ID TOTAL_ROLE_ID CMAT_CUSTOMER_ID CMAT_SITE_ID
451449000141 13 1 6097038 9409647
451449000141 22 1 6097038 9409647

One method is to use not exists:
select t.*
from t
where (role_id = 13 and
not exists (select 1 from t t2 where t2.cmat_customer_id = t.cmat_customer_id and t2.role_id = 22)
) or
(role_id = 22 and
not exists (select 1 from t t2 where t2.cmat_customer_id = t.cmat_customer_id and t2.role_id = 13)
);

Related

T-SQL How to configure Group by so that specific values would be correctly shown

My current T-SQL query provides the following results:
Query:
WITH CTE AS
(
SELECT SubscriberID, sum(valueMB) as ValuesMB
FROM dbo.InternetNetwork
GROUP BY SubscriberID
),
CTE2 AS (
SELECT ab.planID, a.SubscriberID, MAX(ValuesMB) as MaximumValue
FROM CTE AS a
left join
Subscriber as ab on a.SubscriberID= ab.SubscriberID
GROUP BY ab.planID, a.SubscriberID
)
select *
FROM CTE2 as b
ORDER BY b.MaximumValue desc
Output:
planID | SubscriberID | MaxValue
19 1555 97536.00
18 3528 97478.00
2 4029 93413.00
Query #2:
WITH CTE AS
(
SELECT SubscriberID, sum(valueMB) as ValuesMB
FROM dbo.InternetNetwork
GROUP BY SubscriberID
),
CTE2 AS(
SELECT ab.planID, MAX(ValuesMB) as MaximumValue
FROM CTE AS a
left join
Subscriber as ab on a.SubscriberID= ab.SubscriberID
GROUP BY ab.planID
)
SELECT pl.OperatorID, MAX(b.MaximumValue) as Super
FROM CTE2 as b
left join
Plan as pl on b.planID= pl.planID
GROUP BY pl.operatorID
ORDER BY pl.operatorID
Output #2:
OperatorID | Value
1 93413.00
2 86017.00
3 97536.00
I would like to also include a subscriberID, but I'm unable to figure out a way to do so, as the only way to do it, is including in the last SELECT and adding to GROUP BY, which when done, makes a mess of a result which is not accurate.
My desired output:
OperatorID | Value | SubscriberID
1 93413.00 4029
2 86017.00 164
3 97536.00 1544
internet network data:
SubscriberID ValuesMB
1 28
1 27
2 27
2 27
2 27
3 29
3 28
3 27
3 27
4 27
4 27
4 29
Subscriber Data:
SubscriberID PersonID PlanID
1 1 3
2 2 10
3 2 6
4 3 14
5 3 1
6 4 18
7 5 5
8 5 1
9 5 9
10 5 16
11 6 13
12 6 13
13 6 20
14 6 16
15 7 4
Plan data
PlanID OperatorID
1 1
2 1
3 2
4 2
5 2
6 2
7 2
8 2
9 2
10 2
11 2
12 3
13 3
14 3
15 3
16 3
17 3
18 3
19 3
20 3
The tables are somewhat like this related InternetNetwork-> Subscriber -> Plan. InternetNetwork contains how much each Subscribed has used. Each Subscriber has Plan associated with him. Each Plan contains a different Operator, there are only three. I wish to list all three operators, the data transferred by the subscriber of the plan that has the operator and Subscriber ID.
Window functions allow you to have fields in your select along with aggregate functions. You can do something like this
;WITH CTE AS
(
SELECT I.SubscriberID,
S.PlanID,
SUM(ValuesMB) OVER(PARTITION BY i.SubscriberID)as ValuesMB
FROM dbo.InternetNetwork I
JOIN Subscriber S
ON I.SubscriberID = S.SubscriberID
),
CTE2 AS
(
SELECT p.operatorID,
a.SubscriberID,
a.ValuesMB,
ROW_NUMBER() OVER(PARTITION BY p.operatorID ORDER BY a.ValuesMB DESC) as rn
FROM CTE a
join [Plan] P
on a.planID = P.planID
)
SELECT operatorID,
ValuesMB,
SubscriberID
FROM CTE2
where rn = 1

Unable to use LAG function

I need to update a table as :
ID | START_DATE | response| FINAL_TREND
1 14-10-2021 4
1 15-10-2021 3
1 16-10-2021 2
1 17-10-2021 2
1 18-10-2021 3
1 19-10-2021 2
OUTPUT AS:
ID | START_DATE | response| FINAL_TREND
1 14-10-2021 4 NULL
1 15-10-2021 3 4
1 16-10-2021 2 3
1 17-10-2021 2 2
1 18-10-2021 3 2
1 19-10-2021 2 3
So, when running a code:
SELECT LAG(RESPONSE,1) OVER (ORDER BY START_DATE) AS NEW
FROM DUMMY_YC
Output as:
NULL
4
3
2
3
2
2
But when using same code in update AS:
UPDATE DUMMY_YC A SET A.RESPONSE = (SELECT LAG(B.RESPONSE,1) OVER (ORDER BY B.START_DATE) AS NEW
FROM DUMMY_YC B WHERE B.START_DATE=A.START_DATE)
output as:
7 rows updated.
But the actual updated value is
RESPONSE|
(null)
(null)
(null)
(null)
(null)
(null)
(null)
Helps will be appreciated. Working On Oracle SQL Developer.
I'd go with merge.
Before:
SQL> SELECT *
2 FROM test
3 ORDER BY id, start_date;
ID START_DATE RESPONSE FINAL_TREND
---------- ---------- ---------- -----------
1 14.10.2021 4 0
1 15.10.2021 3 0
1 16.10.2021 2 0
1 17.10.2021 2 0
1 18.10.2021 3 0
1 19.10.2021 2 0
6 rows selected.
Merge:
SQL> MERGE INTO test a
2 USING (SELECT b.id,
3 b.start_date,
4 b.response,
5 LAG (b.response, 1) OVER (ORDER BY b.start_date) AS final_trend
6 FROM test b) x
7 ON ( x.id = a.id
8 AND x.start_date = a.start_date)
9 WHEN MATCHED
10 THEN
11 UPDATE SET a.final_trend = x.final_trend;
6 rows merged.
After:
SQL> SELECT *
2 FROM test
3 ORDER BY id, start_date;
ID START_DATE RESPONSE FINAL_TREND
---------- ---------- ---------- -----------
1 14.10.2021 4
1 15.10.2021 3 4
1 16.10.2021 2 3
1 17.10.2021 2 2
1 18.10.2021 3 2
1 19.10.2021 2 3
6 rows selected.
SQL>

Select Command return Duplicate Rows

I have 3 tables:
Table 1 ExamTB:
ID ExamTerm ExamDate
1 MidTerm 2017-09-24
2 FinalTerm 2017-12-01
Table 2 ExamSubMarksTB
ID ExamID ClassID SubjectID TotalMarks PassMarks
1 1 1 1 100 50
2 1 1 2 100 50
3 1 1 3 100 50
4 2 1 1 100 50
5 2 1 2 100 50
6 2 1 3 100 50
Table 3 ExamResultTB
ID ExamID ClassID SubjectID MarksObtain StdID
1 1 1 1 80 1
2 1 1 2 70 1
3 1 1 3 60 1
4 2 1 1 50 1
5 2 1 2 72 1
6 2 1 3 68 1
Now when I create a Stored Procedure the SELECT this Select Command returns duplicate rows
SELECT ExamResultTB.ExamID
, ExamTB.ExamTerm
, ExamTB.ExamDate
, ExamResultTB.StdID
, StudentTB.Name
, StudentTB.FatherName
, ClassTB.ClassName
, SubjectTB.Subject
, ExamResultTB.ObtainMarks
, ExamSubMarksTB.TotalMarks
, ExamSubMarksTB.PassMarks
FROM ExamResultTB
INNER JOIN ExamTB ON ExamResultTB.ExamID = ExamTB.ID
INNER JOIN ClassTB ON ExamResultTB.ClassID = ClassTB.ID
INNER JOIN SubjectTB ON ExamResultTB.SubjectID = SubjectTB.ID
INNER JOIN StudentTB ON ExamResultTB.StdID = StudentTB.ID
INNER JOIN ExamSubMarksTB ON ExamResultTB.ExamID = ExamSubMarksTB.ExamID
WHERE ExamResultTB.ExamID = 4
AND ExamResultTB.StdID=1
For sure this line make a duplicate row:
INNER JOIN ExamSubMarksTB ON ExamResultTB.ExamID = ExamSubMarksTB.ExamID
You should do it in this way:
INNER JOIN ExamSubMarksTB ON ExamResultTB.ExamID = ExamSubMarksTB.ExamID and
ExamResultTB.ClassId = ExamSubMarksTB.ClassId and ExamResultTB.SubjectID =
ExamSubMarksTB.SubjectID

How to check id-s of parents and then set value

I have table like this :
ID object_id parent_id allowed
1 1 0 0
2 23 25 1
3 25 44 0
4 44 38 0
5 38 1 0
6 52 55 1
7 55 58 0
8 58 60 0
9 60 1 0
Now want select row-s where allowed = 1 and then set allowed = 1 for parents of the row which i select. For example it will be like :
step 1. select object_id , parent_id from myTbl where allowed = 1 Displays:
ID object_id parent_id allowed
2 23 25 1
6 52 55 1
step 2: It checks if the object_id is IN the parent_id from the above result and sets allowed = 1 when the object_id is equal to any of the parent_id's.
The exact same step2 repeats until it reaches a point where there is no match between object_id and parent_id
ID object_id parent_id allowed
2 23 25 1
6 52 55 1
3 25 44 0 --update to 1
7 55 58 0 -- update to 1
The exact same principle is being applied to the folling records, too:
for 25,44,1 - 44,38,0 (allowed is 0 want set 1) when set allowed = 1 it will be
44,38,1
for 55,58,1 - 58,60,0 (allowed is 0 want set 1) when set allowed = 1 it will be
58,60,1
How to do it ? In table My table contains multiple records with status allowed=1 and only 2 of them are used in this particular example.
Try:
UPDATE tbl
SET allowed = 1
FROM (SELECT *
FROM tbl
WHERE allowed = 0) A
INNER JOIN
(SELECT *
FROM tbl
WHERE allowed = 1) B
ON A.objectid = B.parentid

Calculate sum data and insert into another in SQL

I need to calculate sum of hours based on period column and insert into another table. Please see below example data.
[code]
tbl_Summary
Client_id Store_id attribute1 Period Hours attributes
1 16 1 2/25/2007 1054.8 1
1 16 1 3/11/2007 1112.8 1
1 16 1 3/25/2007 1164.8 1
1 16 1 4/8/2007 1383.2 1
1 16 1 4/22/2007 1351.6 1
1 16 1 9/21/2008 1523.6 1**
1 16 1 10/5/2008 1020.26 1
1 16 1 10/19/2008 939.94 1
1 16 1 11/2/2008 903.14 1
1 16 1 8/9/2009 866.66 1
1 16 1 8/23/2009 915.48 1
1 16 1 9/6/2009 894.26 1
1 16 1 9/20/2009 1458.58 1[/b]
1 18 1 6/1/2008 1112.8 1
1 18 1 6/15/2008 1164.8 1
1 18 1 6/29/2008 1383.2 1 [b]
1 18 1 7/13/2008 1351.6 1
1 18 1 12/28/2008 1523.6 1
1 18 1 1/11/2009 979.2 1
1 18 1 1/25/2009 913.2 1
1 18 1 2/8/2009 930.6 1
1 18 1 2/22/2009 1143.4 1
1 18 1 5/31/2009 1066.16 1
1 18 1 6/14/2009 1174.8 1
1 18 1 6/28/2009 1099.2 1
1 18 1 7/12/2009 1014.5 1
Out put table will be like this.
tbl_history
--------------
[code]client_id store_id attribute1 hours attributes
1 16 1 8521.92 1
1 18 1 11196.92 1
Conditions for sp
Parameters to sp are only #client_id, #attribute1, #attributes
Find Max(Period) and go back to 52 weeks and calculate Sum(Hours) where Store_id= ? (in example 16 and 18 or each store_id) and client_id= #client_id and attribute1 = #attribute1 and attributes = #attributes. ie. Sum(Hours) will change based on store_id and when store_id will change period will change. See side moved data
store_id = 16 and period=9/20/2009 to 9/20/2009 sum(hours) =8521.92
Insert into another table all output tbl_history.
Please give me solution. If you have any question ask me.
Thanks in advance
INSERT INTO tbl_history
SELECT client_id, store_id, attribute1, SUM(Hours), attributes
FROM tbl_Summary
WHERE PERIOD <=
(
SELECT MAX(PERIOD)
FROM tbl_Summary
WHERE client_id = #client_id
AND attribute1 = #attribute1
AND attributes = #attributes
)
AND PERIOD >=
(
SELECT (MAX(PERIOD) - 1 year) --(I dont remember the sintax for sql getdate() something but thats the idea)
FROM tbl_Summary
WHERE client_id = #client_id
AND attribute1 = #attribute1
AND attributes = #attributes
)
AND client_id = #client_id
AND attribute1 = #attribute1
AND attributes = #attributes
GROUP BY client_id, store_id, attribute1, attributes
Try it and tell me if it worked.
Regards.