create total accordif if column is filled - sql

I want to count the number of total people who will attend to an event and this number is calculated by the person who invites and how many people will be invited.
So I have this info,
refInqCredLink RegisterDate Name Phone Email Horario Insc1 Insc2 Insc3
496 2019-08-29 15:38:13.183 Abilio 91 abilio#hotmail.com 3 albano jorge
497 2019-08-30 14:12:46.873 Duarte 25 duarte#sapo.pt 3 antonio
499 2019-08-30 14:48:29.067 AGOSTINHO 92 agostinho#gmail.com 1 Jorge Antonio Manuel Fernando
In this case "John" will attend the event and will invite "albano" and "jorge". So the total number of people in this line is 3.
I need to check if Insc1, Insc2 and Insc3 column have value and if so (<>'') count as 1 person. I need to create a view based in this table with this sum.
If I try this code,
Select
SUM(case when not Name is null then 1 else 0 end
+
case when not Insc1 is null then 1 else 0 end
+
case when not Insc2 is null then 1 else 0 end
+
case when not Insc3 is null then 1 else 0 end)
from LACTINFO_InquiryCredential_Link_Seminario
this returns 12 instead of 8.
I have 3 Names + 5 Invitees = 8

Try the following
Select
SUM(case when Insc1 is null or Insc1 = '' then 0 else 1 end
+
case when Insc2 is null or Insc2 = '' then 0 else 1 end
+
case when Insc3 is null or Insc3 = '' then 0 else 1 end)
+
count(*)
from tab

To get the total, you can use count():
select count(*) + -- everyone is counted once
count(insc1) + count(insc2) + count(insc3) -- additional invitees
from t;
First, note that this is a poor data model. You should have a separate table with one row per person invited.
Second, the same person could be invited multiple times. This formulation does not take that into account. Using just first names makes it hard to deduplicate the data.

Related

Organizing data into multiple columns SQL

I have a table of more than 5m customers with historic activity data as in example below:
Customer ID
PART_ID
Activity
12345
202012
2
12345
202101
0
12345
202102
5
I want to convert this data into multiple columns; customers at the rows, dates in the columns and their respective activity info.
I wrote the code below but instead of creating a single row for a single customer, customers duplicate and I get a table like this:
Customer ID
202012
202101
202102
12345
1
0
0
12345
0
0
0
12345
0
0
1
Instead of:
Customer ID
202012
202101
202102
12345
1
0
1
What am I doing wrong?
SELECT *
FROM
(
SELECT CUST_ID, RULLED_PROFIT_CENTER,
CASE WHEN PART_ID = 202012 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS ARA_20,
CASE WHEN PART_ID = 202101 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS OCA_21,
CASE WHEN PART_ID = 202102 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS SUB_21,
CASE WHEN PART_ID = 202103 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS MAR_21,
CASE WHEN PART_ID = 202104 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS NIS_21,
CASE WHEN PART_ID = 202105 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS MAY_21,
CASE WHEN PART_ID = 202106 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS HAZ_21,
CASE WHEN PART_ID = 202107 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS TEM_21,
CASE WHEN PART_ID = 202108 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS AGU_21,
CASE WHEN PART_ID = 202109 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS EYL_21
FROM ACTIVITY
WHERE RULLED_PROFIT_CENTER IN (108, 103, 170)
GROUP BY CUST_ID, RULLED_PROFIT_CENTER
)
WHERE ARA_20 + OCA_21 + SUB_21 + MAR_21 + NIS_21 + MAY_21 +
HAZ_21 + TEM_21 + AGU_21 + EYL_21 > 0
WHERE RULLED_PROFIT_CENTER IN (108, 103, 170)
GROUP BY CUST_ID, RULLED_PROFIT_CENTER
You're grouping by two values, the customer and RULLED_PROFIT_CENTER. RULLED_PROFIT_CENTER can have three possible values, so you're going to get up to three rows per customer. If you want only one row per customer, remove RULLED_PROFIT_CENTER from your group by.
It's possible you added RULLED_PROFIT_CENTER to the group by because the query didn't work without it. If you want to include RULLED_PROFIT_CENTER in your select, but not your group by, you need to aggregate RULLED_PROFIT_CENTER as well. Even if each customer only has one value for it. Use string_agg.
SELECT CUST_ID, string_agg(RULLED_PROFIT_CENTER, ', ')
If a customer has only one value for RULLED_PROFIT_CENTER you'll get just that one value.
Since you're grouping all the rows of a customer together, you will need to take the max of your activities.
MAX( CASE WHEN PART_ID = 202012 AND ACTIVITY > 0 THEN 1 ELSE 0 END ) AS ARA_20

Creating extra columns based on condition (Case When Sum)

I have survey table where someone is asked roughly 5 questions. 4 of those questions are the same questions, but the options to their answers are different since they were to understand their purchase.
Here are the questions:
ID Question qid Answer
101005 what brands did you purchase the past 5 months 1 Coca-Cola or Pepsi or Dr.Pepper
101005 what brands did you purchase the past 5 months 1 Dr.Pepper
101005 what brands did you purchase the past 5 months 1 store brand
101005 what brands did you purchase the past 5 months 1 Coca-Cola
101005 how many people live in your house 4 4
101005 what is your prefer retailers 8 walmart
The goal is to create four extra columns based on their answer and they will be assigned a 1 or 0. Since this person's answer is coca cola, I want to assign them in the column of current_buyer and give them 1 and 0 will be new_buyer column. I also want to make sure that even though he answer Dr.Pepper in the second row, it still recognizes him as a current_buyer. In the same breath I want to assign this person a 1 in the 3rd column as a drinker and 0 4th column in prospect.
Here is how the table should look like
ID Question qid answer Current_buyer New_buyer drinker prospect
101005 what brands did you purchase the past 5 months 1 Coca-Cola or Pepsi or Dr.Pepper 1 0 1 0
101005 what brands did you purchase the past 5 months 1 Dr.Pepper 1 0 1 0
101005 how many people live in your house 4 4 1 0 1 0
The goal is to see if ID bought coca-cola the past 5 months, they are a current buyer (1) and drinker (1) and will have (0) for new_buyer and prospect in their entire profile.
Here is the code that I try:
select ID,qid,question,answer,s_date,
Case when Sum(Case when [answer] like'%coca-cola%' then 1 else 0 end)>=1 then 1
else 0 end current_buyer
,Case when Sum(Case when [answer] like'%coca-cola%' then 1 else 0 end)=0 then 1
else 0 end New_buyer
,Case when Sum(Case when [answer] like'%coca-cola,Dr.pepper,pepsi%' then 1 else 0 end)>=1 then 1
else 0 end drinker
,Case when Sum(Case when [answer] like'%coca-cola,Dr.pepper,pepsi%' then 1 else 0 end)=0 then 1
else 0 end Prospect
Unfortunately, using this code I'm getting 0 in the drinker column even though people selected coca-cola. Any help would be appreciated.
I'm not 100% sure that I understand the logic behind assigning the various values, but in general it seems that you are assigning the value based on an aggregation of multiple rows. Therefore you need to do the aggregation first (in this case in a CTE) and then join back to that for your query.
Also worth noting is that even though your are doing your matching with a LIKE operator - everything between the [%] characters will need to match exactly somewhere in your [answer]. I don't think that this is what you want - so I've split them out. However I'm not 100% sure if I've got the logical operators completely correct.
Do you need something like:
;with analysisCTE as (select ID,qid,
Case when Sum(Case when [answer] like'%coca-cola%' then 1 else 0 end)>=1 then 1
else 0 end current_buyer
,Case when Sum(Case when [answer] like'%coca-cola%' then 1 else 0 end)=0 then 1
else 0 end New_buyer
,Case when Sum(Case when [answer] like'%coca-cola%' OR [answer] like '%Dr.pepper%' OR [answer] like '%pepsi%' then 1 else 0 end)>=1 then 1
else 0 end drinker
,Case when Sum(Case when [answer] like'%coca-cola%' OR [answer] like '%Dr.pepper%' OR [answer] like '%pepsi%' then 1 else 0 end)=0 then 1
else 0 end Prospect
from drinks
group by id, qid)
select d.ID,d.qid,d.question,d.answer, a.current_buyer, a.New_buyer, a.drinker, a.Prospect
from drinks d
inner join analysisCTE a on d.id = a.id and d.qid = a.qid

SQL: Combine Duplicate Rows And Case Statement Values in Final Data Output

I'm working on a SQL query that counts duplicate records that are based on a text field I am working with: where datasource = 'Web' or 'Internal'. I am currently using a case statement to count the number of times a record shows that value. My question is how do I combine the two results into one record that shows a count of both.
I'm attaching a query of what I currently have working, what my output is and what I would like the end result to look like.
SELECT id
,lastname
,firstname
,datasource
,CASE
WHEN (
(Datasource = 'Web')
)THEN Count(Datasource)
ELSE 0
END WebData
,CASE
WHEN (
(Datasource = 'Internal')
) THEN Count(Datasource)
ELSE 0
END InternalData
,count(id) as countid
FROM Table
GROUP BY
id
,lastname
,firstname
,datasource
This currently returns:
12345 Jack Boss Internal 0 1 1
12241 Eric Graves Internal 0 1 1
13300 Su Lynn Web 1 0 1
13300 Su Lynn Internal 0 1 1
13914 Mark Ross Internal 0 2 2
14008 Mitch Smith Internal 0 1 1
I would like it to return:
12345 Jack Boss 0 1 1
12241 Eric Graves 0 1 1
13300 Su Lynn 1 1 2
13914 Mark Ross 0 2 2
14008 Mitch Smith 0 1 1
Thanks
You need to add the outer select for current query with the Group on the the columsn you want to do the aggrigate.Just add the Outer select to your query,
SELECT
data.id,
data.lastname,
data.firstname,
SUM(data.WebData) AS WebData,
SUM(data.InternalData) AS InternalData,
SUM(data.countid) AS Countid
FROM
(
SELECT id,lastname,
firstname,datasource,
CASE WHEN Datasource = 'Web' THEN Count(Datasource) ELSE 0 END WebData,
CASE WHEN Datasource = 'Internal' THEN Count(Datasource)ELSE 0 END InternalData,
count(id) AS Countid
FROM Table
GROUP BY
id,lastname,firstname,datasource
) AS data
GROUP BY
data.id,data.firstname,data.lastname

How to apply answer key on students' responses

I conducted a MCQs type test for students in Eng, math, and science
Students solved their test on a sheet readable by the OMR/OCR.
The machine produced responses of the students in follwoig way:-
Student ID Subject Q1 Q2 Q3 Q4 ......
201 English 3 1 4 1 ......
201 Math 3 2 1 1 ....
201 Science 2 1 2 3 ....
202 English 3 1 4 1 ......
202 Math 3 2 1 1 ....
202 Science 2 1 2 3 ....
-
-
-
How can i apply answer key on this data e.g for English my answer key is:
2 2 4 1 .....
would you pleas suggest a query for this situation
SELECT
StudentId
,CASE WHEN Q2 = ?ANSWER? then 1 ELSE 0 END
,CASE WHEN Q3 = ?ANSWER? then 1 ELSE 0 END
,CASE WHEN Q4 = ?ANSWER? then 1 ELSE 0 END
,CASE WHEN Q5 = ?ANSWER? then 1 ELSE 0 END
FROM
Table
Where subject = 'English'
One of possible solutions replace ?ANSWER? with something from your answer key
Other would be to generate tables like:
CREATE TABLE EnglishKey(
QuestionId int,
Answer int)
Then insert your values in this way:
INSERT INTO EnglishKey VALUES (1,3),(2,4),(....)
Replacing 1 with question number and answer with proper answer.
And then creating a SELECT should be easy
SELECT
a.StudentID
CASE WHEN a.Q1 <> a.A1 THEN 0 ELSE 1 end AS Result1,
CASE WHEN a.Q2 <> a.A2 THEN 0 ELSE 1 end AS Result2,
CASE WHEN a.Q3 <> a.A3 THEN 0 ELSE 1 end AS Result3,
CASE WHEN a.Q4 <> a.A4 THEN 0 ELSE 1 end AS Result4,
CASE WHEN a.Q5 <> a.A5 THEN 0 ELSE 1 end AS Result5,
CASE WHEN a.Q6 <> a.A6 THEN 0 ELSE 1 end AS Result6,
CASE WHEN a.Q7 <> a.A7 THEN 0 ELSE 1 end AS Result7,
CASE WHEN a.Q8 <> a.A8 THEN 0 ELSE 1 end AS Result8
FROM
StudentTable a
INNER JOIN AnswerTable b ON a.[SUBJECT] = b.[SUBJECT]
This answer presumes that you have the answers in a seperate table and can join on subject.
If you find it a pain to write out all the case statements (could have 100s of questions) you can quickly build these queries in Microsoft Excel or open office by breaking up the statement across multiple columns, have it fill in the 1,2,3,4s etc and then copy paste once happy.

Counting similar values on same row, different columns

I want to write a query that will count how many times a certain value appears on each row - on the full table I have more columns and I need to count how many times "9" (for example) appears in all the columns,
In this case the answer would be 3:
PlayerName Nation Kills Deaths SoloKills PartyKills
666 1 9 0 9 9
select PlayerName
, sum(case when Nation = 9 then 1 else 0 end +
case when Kills = 9 then 1 else 0 end +
case when Deaths = 9 then 1 else 0 end +
...
) as SumOfNines
from YourTable
group by
PlayerName