Problem Using Two Count()'s On Same Column - tsql

I'm trying to get two different counts on the same column. The two counts work fine when in separate queries, but I'm just not sure how to put them together into one query. I have two tables, which are DailyFieldRecord and AB953. DailyFieldRecord contains: DailyFieldRecordID and ActivityCodeID. The AB953 table contains:DailyFieldRecordID, ItemID, and GroupID. Count1 will return the count of the DailyfieldrecordID's that contain ActivityCodeID=387 and GroupID=260 and that DON'T have ItemID in (1302,1303,1305,1306). Count2 will return the count of the DailyfieldrecordID's that contain ActivityCodeID=387 and GroupID=260 and that HAVE ItemID in (1302,1303,1305,1306). So they are similar, but I'm just not sure how to combine them into one query. I put an OR in the where clause between the two constraints, which I know is wrong, but I'm just not sure how to do this.
DailyFieldRecord: AB953:
DailyFieldRecordID ActivityCodeID DailyFieldRecordID: ItemID: GroupID:
657 387 657 1305 210
888 420 657 1333 260
672 387 657 1335 260
888 1302 210
888 1336 260
672 1327 260
672 1334 260
672 1335 260
Expected Output:
Count1: Count2:
3 2
Count1 is supposed to count: Count2 is supposed to count:
672 1327 260 657 1333 260
672 1334 260 657 1335 260
672 1335 260
SELECT COUNT(ActivityCodeID) as Count1, COUNT(ActivityCodeID) As Count2
FROM AB953 ab
JOIN DailyFieldRecordID dfr on
dfr.DailyFieldRecordID=ab.DailyFieldRecordID
WHERE dfr.ActivityCodeID=387 and ab.GroupID=260 and NOT exists(
select b.DailyFieldRecordID
FROM DailyFieldRecordID b
WHERE ab.DailyFieldRecordID = b.DailyFeildRecordID AND
b.ItemID in (1302,1303,1305,1306))
OR
dfr.ActivityCodeID=387 and ab.GroupID=260 and exists(
select b.DailyFieldRecordID
FROM DailyFieldRecordID b
WHERE ab.DailyFieldRecordID = b.DailyFeildRecordID AND
b.ItemID in (1302,1303,1305,1306))

First find the list of DailyFieldRecordID for ItemID in (1302,1303,1305,1306) (Query 1) and then incorporate query to your Final Query.
SQL Fiddle
Query 1:
SELECT AB1.DailyFieldRecordID,SUM(CASE WHEN AB1.ItemID IN (1302,1303,1305,1306) THEN 1 ELSE 0 END)
FROM AB953 AB1
GROUP BY AB1.DailyFieldRecordID
Final Query:
SELECT SUM(CASE WHEN EX=0 THEN 1 ELSE 0 END) AS COUNT1,SUM(EX) AS COUNT2
FROM AB953 ab
INNER JOIN DailyFieldRecord dfr
ON dfr.DailyFieldRecordID = ab.DailyFieldRecordID
LEFT JOIN ( SELECT AB1.DailyFieldRecordID,SUM(CASE WHEN AB1.ItemID IN (1302,1303,1305,1306) THEN 1 ELSE 0 END) AS EX
FROM AB953 AB1
GROUP BY AB1.DailyFieldRecordID) T
ON dfr.DailyFieldRecordID = T.DailyFieldRecordID
WHERE dfr.ActivityCodeID = 387
AND ab.GroupID = 260

Related

SQL Server CTE and recursion example misunderstanding

Could someone help me with cte expresion? I have a table:
old_card
new_card
dt
111
555
2020-01-09
222
223
2020-02-10
333
334
2020-03-11
444
222
2020-04-12
555
666
2020-05-12
666
777
2020-06-13
777
888
2020-07-14
888
0
2020-08-15
999
333
2020-09-16
223
111
2020-10-16
I need to get all the changes of old_card to a new_card, since old_card number 111 to a new_card number 0. So I must get 5 records from this table having only a new_card = 0 as input parameter
old_card
new_card
dt
111
555
2020-01-09
555
666
2020-05-12
666
777
2020-06-13
777
888
2020-07-14
888
0
2020-08-15
I think of to do it using cte, but I get all the records from the source table and can't understand why. Here is my cte:
;with cte as(
select
old_card,
new_card,
dt
from
cards_transfer
where
new_card = 0
union all
select
t1.old_card,
t1.new_card,
t1.dt
from
cards_transfer t1
inner join
cte on cte.old_card = t1.new_card)
But I get 8 rows instead. Can someone tell me please what I did wrong?
You said you wanted from 111 onwards. So you need to add that "stop" condition
where cte.old_card <> 111
;with cte as(
select
old_card,
new_card,
dt
from
cards_transfer
where
new_card = 0
union all
select
t1.old_card,
t1.new_card,
t1.dt
from
cards_transfer t1
inner join
cte on cte.old_card = t1.new_card
where cte.old_card <> 111
)

Problem Displaying Multiple Items From Same Column In One Row

I have three tables, DailyFieldRecord, AB953,and Lookup. The DailyFieldRecord table contains DailyFieldRecordID.The AB953 table contains DailyFieldRecordID,GroupID,LookupID, and PersonID. The Lookup table contains GroupID, Description, and LookupID. I'm trying to display the persons ethnicity, age, and gender in the same row based on each DailyFieldRecordID and PersonID. The problem I'm having is that the descriptions of ethnicity, age, and gender are in the same column in the lookup table. I've tried different ways, but am only able to get the correct information for one person. Any input would be helpful.
DailyFieldRecord: AB953:
DailyFieldRecordID DailyFieldRecordID: LookupID: GroupID: PersonID:
1111 1111 1260 300 1
1111 1262 200 1
1111 1264 310 1
1111 1258 300 2
1111 1261 200 2
1111 1265 310 2
Lookup:
GroupID: Description: LookupID:
300 white 1260
300 latin 1258
200 17 1262
200 18 1261
310 male 1264
310 female 1265
Select ab.DailyFieldRecordID, lkp.Description as
Ethinicity,lkp2.Description as Age, lkp3.Description as Gender,
ab.PersonID
FROM DailyFieldRecord dfr
LEFT JOIN AB953 ab ON ab.DailyFieldRecordID=dfr.DailyFieldRecordID and
ab.GroupID=300 and ab.PersonID=1
LEFT JOIN AB953 ab2 ON ab2.DailyFieldRecordID=dfr.DailyFieldRecordID and
ab2.GroupID=200 and ab2.PersonID=1
LEFT JOIN AB953 ab3 ON ab3.DailyFieldRecordID=dfr.DailyFieldRecordID and
ab3.GroupID=310 and ab3.PersonID=1
LEFT JOIN Lookup lkp ON lkp.LookupID=ab.ItemID
LEFT JOIN Lookup lkp2 ON lkp2.LookupID=ab2.ItemID
LEFT JOIN Lookup lkp3 ON lkp3.LookupID=ab3.ItemID
Current output:
DailyFieldRecordID: Ethnicity: Age: Gender: PersonID:
1111 white 17 male 1
Expected output:
DailyFieldRecordID: Ethnicity: Age: Gender: PersonID:
1111 white 17 male 1
1111 latin 18 female 2
Though i must say, this is very bad DB design, Yet you are getting only first person ID coz you are using PersonID = 1 in the query. Please try below query removing PersonID = 1.
Select ab.DailyFieldRecordID
,MAX(CASE WHEN lkp.GroupID = 300 THEN lkp.Description) as Ethinicity
,MAX(CASE WHEN lkp.GroupID = 200 THEN lkp.Description) as Age
,MAX(CASE WHEN lkp.GroupID = 310 THEN lkp.Description) as Gender
,ab.PersonID
FROM DailyFieldRecord dfr
LEFT JOIN AB953 ab ON ab.DailyFieldRecordID=dfr.DailyFieldRecordID
LEFT JOIN Lookup lkp ON lkp.GroupID=ab.GroupID
GROUP BY ab.DailyFieldRecordID, ab.PersonID

Problem counting items in an individual row without duplication

I'm trying to write a query that will include a count for the primary and secondary activity only when Group ID = 260 and Item id in(1302,1303,1305,1306) for each individual RecordID. So far I have been able to single out the rows with those conditions, but I only want to count the primary and secondary activities once(because the Primary and Secondary activities are the same for their corresponding RecordID regardless of how many rows there are), if they aren't null, regardless of how many RecordID's match those conditions.
RecordID: GroupID: ItemID: PrimActivity: SecActivity:
320 260 1302 36 0
320 260 6456 36 0
320 312 1303 36 0
560 400 1302 46 48
560 312 1305 46 48
460 260 1305 45 56
460 260 1302 45 56
Result I'm getting:
RecordID: Count:
320 2
460 4
Expected result:
RecordID: Count:
320 1
460 2
SELECT dfr.RecordID,
COUNT(CASE WHEN dfr.PrimActivity <> 0 and a.GroupID =260 then 1
ELSE NULL END) +
COUNT(CASE WHEN dfr.SecActivity <> 0 and a.GroupID =260 then 1 ELSE
NULL END) AS Count
From ActivityItem ai
Join DailyRecord dfr on ai.PrimActivity = dfr.PrimActivity
Join AreaInfo af on af.AreaInfoID = dfr.AreaInfoID
Join Information a on dfr.RecordID = a.RecordID
Join Lookup lp on lp.ItemID = a.ItemID
WHERE a.GroupID like '260' and EXISTS(
SELECT b.RecordID, b.GroupID, b.ItemID
FROM Areainfo b
where a.RecordID=b.RecordID and b.ItemID IN(1302,1303,1305,1306)
GROUP BY dfr.RecordID
You should be more clear when you explain the structure of tables you are using. However, I reach the expected result starting from your sample table doing this:
SELECT RecordID,COUNT(*) as Count
FROM (SELECT DISTINCT RecordID,ItemID,PrimActivity,SecActivity
FROM [TABLE YOU POSTED]
WHERE GroupID = 260 and ItemID in (1302,1303,1305,1306) ) A
GROUP BY RecordID

Problem Counting Items For an Individual Row

I need to find the count for ActivityID and AdditionalActivityID for each DailyFieldRecordID based on when GroupID = 260 and ItemID is either 1302,1303,1305,1306. The problem I'm having is that regardless of how many rows for each individual DailyFieldRecordID there are, there can only be one ActivityID and one AdditionalActivityID regardless of how many rows comply with the constraints.
Say someone is filling out a form and they list what their Activity for the day was and also what other activity they might have. They can only list one primary activity(ActivityID) and one secondary activity(AdditionalActivity). But during those activities they could participate with multiple groups(GroupID) or people(ItemID). So when I'm running this query I'm able to separate the rows based on the constraints, but I only want to count how many activities they participated in, which will either be 1 or 2 for each DailyFieldRecordID, regardless of how many groups or people were involved. Right now my query is counting each ActivityID and AdditionalActivityID for each row that meets the criteria, which can give me many more than just 1 or 2 for each DailyFieldRecordID. I'm just not sure how I would go about doing this. Any feedback is greatly appreciated.
DailyFieldRecordID: GroupID: ItemID: ActivityID: AdittionalActivityID:
3369320 260 1302 37 0
3369320 260 1305 37 0
3369320 210 2222 37 0
3369320 250 2222 37 0
3372806 260 1302 56 56
3372806 260 1305 56 56
3372806 250 2222 56 56
3388888 260 2222 45 32
Expected Result:
DailyFieldRecordID: Count:
3369320 1
3372806 2
Current Result:
DailyFieldRecordID: Count:
3369320 2
3372806 4
'
select a.DailyFieldRecordID,
count(case when a.ActivityID <>0 then 1 else null end) +
count(case when a.AdditionalActivityID <>0 then 1 else null end) as count
from AB953 a
where a.GroupID= 260 and exists(
select b.DailyFieldRecordID
from AB953 b
where a.DailyFieldRecordID = b.DailyFieldRecordID and b.ItemID in (1302,1303,1305,1306))
group by DailyFieldRecordID
I get this result when trying your data:
DailyfieldrecordID Count
3369320 3
3372806 2
3388888 1
SELECT DailyFieldRecordID,
COUNT(CASE WHEN ActivityID <>0 then 1 else 0 end +
CASE WHEN AdditionalActivityID <>0 then 1 else 0 end) as Count
from Foo
where GroupID= 260 and exists(
select b.DailyFieldRecordID
from fOO b
where DailyFieldRecordID = b.DailyFieldRecordID and b.ItemID in (1302,1303,1305,1306))
group by DailyFieldRecordID
New query: you might need to fiddle with this, not sure if your data is wrong or not....... cant get it to select 3 and then 2:
SELECT DailyFieldRecordID,
COUNT(CASE WHEN ActivityID <>0 then 1 else 0 end +
CASE WHEN AdditionalActivityID <>0 then 1 else 0 end) as Count
from Foo
where GroupID= 260 and DailyFieldRecordID IN(
select b.DailyFieldRecordID
from fOO b
where b.ItemID IN(1302,1303,1305,1306))
group by DailyFieldRecordID
This should do it:
;WITH CTE AS
(
SELECT A.DailyFieldRecordID
,ActivityID = IIF(A.ActivityID = 0, NULL, A.ActivityID)
,AdittionalActivityID = IIF(A.AdittionalActivityID = 0, NULL, A.AdittionalActivityID)
FROM AB953 A
WHERE A.GroupID = 260
AND A.ItemID IN (1302,1303,1305,1306)
)
SELECT DailyFieldRecordID
,CNT = COUNT(DISTINCT ActivityID) + COUNT(DISTINCT AdittionalActivityID)
FROM CTE
GROUP BY DailyFieldRecordID;
I created this DDL and test data for testing:
DROP TABLE IF EXISTS AB953
GO
CREATE TABLE AB953 (
DailyFieldRecordID INT, GroupID INT, ItemID INT, ActivityID INT, AdittionalActivityID INT)
INSERT INTO AB953
VALUES
( 3369320, 260, 1302, 37, 0 )
,( 3369320, 260, 1305, 37, 0 )
,( 3369320, 210, 2222, 37, 0 )
,( 3369320, 250, 2222, 37, 0 )
,( 3372806, 260, 1302, 56, 56 )
,( 3372806, 260, 1305, 56, 56 )
,( 3372806, 250, 2222, 56, 56 )
,( 3388888, 260, 2222, 45, 32 )
GO

How to get those rows where all the values are same against unique id

I have below mentioned table:
ID State City Pincode Code Date
U-1 AAB CCV 141414 121 2018-04-04 18:08:17
U-1 AAB CCV 141414 121 2018-04-04 18:08:17
U-2 BTB ERV 150454 145 2018-05-05 19:11:25
U-2 BTB ERV 150454 145 2018-05-05 19:11:25
U-3 FFT ERT 160707 150 2018-05-22 21:37:45
U-4 FFT RTT 160707 150 2018-05-28 14:23:48
I want to fetch only those rows where all the values are same in the particular unique ID.
Output:
ID State City Pincode Code Date
U-1 AAB CCV 141414 121 2018-04-04 18:08:17
U-1 AAB CCV 141414 121 2018-04-04 18:08:17
U-2 BTB ERV 150454 145 2018-05-05 19:11:25
U-2 BTB ERV 150454 145 2018-05-05 19:11:25
Get the duplicate rows and join the result to the original table.
select * from table a
join ( select id,state,city,pincode,code,date
from table
group by id,state,city,pincode,code,date
having count(*) > 1 ) b
on a.id = b.id
and a.state = b.state
and a.city = b.city
and a.pincode = b.pincode
and a.code = b.code
and a.date=b.date
You can try this:
SELECT * FROM table WHERE ID IN (
SELECT count(*) AS c FROM table
WHERE c > 1
GROUP BY ID
)
Get all rows where count of the records with this ID is greater than 2 (at least two rows with this id)