How to exclude users with multiple options sql - sql

Trying to retrieve just users that don't have a disabled campaign, where disabled = 1.
A user can have a disabled campaign and a non-disabled campaign, but if they have any disabled campaigns I want to exclude them from my final result.
Thinking I need something like
SELECT DISTINCT
user_id,
CASE
WHEN
disabled = 1
THEN
'Disabled'
ELSE
'Good'
END
AS campaign_disabled
But this just returns two rows for each user_id, one being Good and the other campaign_disabled

You want the users that have disabled = 0 for all their campaigns, so the max value of the column disabled must be 0:
SELECT user_id
FROM tablename
GROUP BY user_id
HAVING MAX(disabled) = 0

Related

SQL query case when at least one

How to use CASE to show 'debtor' if at least one of the invoices is not paid (Invoice_Status = 1)?
*(A customer has multiple invoices)
Here's the query to show the an Id_Customer and the status of his multiple invoices, but this repeats the Id_Customer for each invoice he has
SELECT Id_Customer,
CASE Invoice_Status
WHEN 1 THEN 'Debtor'
ELSE 'No debts'
END AS Status
FROM Tb_Invoices
ORDER BY Id_Customer
GO
You need to use an aggregate (min, max, count etc) on Invoice_Status, then map that value via you case statement. You haven't told us about your schema or data so we can't really help you more than that. I.e. something like this:
SELECT CASE
WHEN count(Invoice_Status = 1) > 0 THEN 'Dector'
ELSE 'No debts'
END
FROM Tb_Invoices
ORDER BY Id_Customer

Computing conversion rate by counting TRUE/FALSE statements

Sorry if this sounds very basic; bear with me.
I need to determine the conversion rate of 3 ads, each representing a product; that would be subscription divided by the number of people who clicked the ad.
COLUMNS:
person_id - unique identifier of the person
date - date they were shown the ad
ad_id - content of the ad: ad_1_product1, ad_2_product2, or ad_3_product3
clicked (TRUE/FALSE) - clicked on the ad
signed_up - (TRUE/FALSE) created an account
subscribed (TRUE/FALSE) - started a paid subscription
I set clicked, signed_up and subscribed as boolean.
MY CODE:
SELECT ad_id, (count(subscribed) / count(clicked)) as CR
FROM videoadcampaign
WHERE subscribed = 'TRUE' AND clicked = 'TRUE'
GROUP BY ad_id;
Of course, the code above gives me a ratio of 1, because SQL is still counting the total and dividing by the same number because of those conditions.
I am totally stuck.
I will also need to calculate other KPIs for clicks and signed_up, so filtering those booleans and put them into a ratio is the core of what I need to do.
Is there a way I can tell SQL to compute CR = SUBS (TRUE) / SUBS (TRUE + FALSE) [or total count] and then filter by CLICK = TRUE?
Thank you tons for your help!
It depends on your database, but the general notion would be:
SELECT ad_id,
(SUM(CASE WHEN subscribed = 'TRUE' THEN 1.0 ELSE 0 END) /
SUM(CASE WHEN clicked = 'TRUE' THEN 1 ELSE 0 END)
) as CR
FROM videoadcampaign
GROUP BY ad_id;
In many databases, you can do something like this if the columns are integers (0 = false, 1 = true):
SELECT ad_id, SUM(subscribed) / SUM(clicked) as CR
FROM videoadcampaign
WHERE clicked = 'TRUE'
GROUP BY ad_id;
Or even:
SELECT ad_id, AVG(subscribed) as CR
FROM videoadcampaign
WHERE clicked = 'TRUE'
GROUP BY ad_id;

How can I count field value based on another field?

I have EmailEvent table. This is STI table which stores opens and clicks (by using type attribute). I have right now this code which provides information on how many emails use recipient address (email_address field):
EmailEvent.where("type = 'OpenEmailEvent' OR type = 'ClickEmailEvent'")
.where(email_id: email_ids).happened_between_dates(start_date, end_date)
.select("email_address, count(distinct email_id) as emails_count")
.group(:email_address).reorder(nil)
It generates such code:
SELECT email_address, count(distinct email_id) as emails_count
FROM "email_events"
WHERE "email_events"."deleted_at" IS NULL
AND (type = 'OpenEmailEvent' OR type = 'ClickEmailEvent')
AND "email_events"."email_id" IN (85487, 75554, 85489, 77184, 78562, 75587, 82879, 85535, 85534)
AND (created_at between '2017-02-28 22:52:01.000000' AND '2017-03-29 05:59:59.000000')
GROUP BY "email_events"."email_address"
I need to provide information on how many opens and clicks there per email_address. I can't use count(id) because it'll give me both opens and clicks so I need to use type attribute somehow but I can't figure out exactly how it should work. Can somebody give me suggestion what should I do here?
replace this
count(distinct email_id) as emails_count
to something like in SQLServer using case or IIF
sum(case when type = 'OpenEmailEvent' then 1 else 0 end) [Opens],
sum(case when type = 'ClickEmailEvent' then 1 else 0 end) [Click],

SQL Query for Access Pie chart - Group By one field but group certain values

Trying to automatically produce a piechart in access which will show me 3 values (completed, pending and queued)
However in my status field I have several values for pending (sent, monitoringStage1, monitoringStage2, finalApproval)
My query at present gives me the count of each item individually:
SELECT Status, Count(*) AS [Count]
FROM StatusTable
GROUP BY Status
ORDER BY Status;
How would I edit it to count sent, monitoringStage1, monitoringStage2, and finalApproval as one item called pending?
Also on a side note, does anybody know how to put a line at a certain point on a piechart by percentage? So in the piechart created I could have a line to indicate the target number of completed items to compare against current progress.
You can't use CASE in a query, only in VBA.
This will take care of it:
SELECT qryTestx.ThisStatus, Count(qryTestx.Status) AS CountOfStatus
FROM (SELECT (IIf([StatusTable.Status] in ("sent","monitoringStage1","monitoringStage2","finalApproval"),"Pending",[StatusTable.Status])) AS ThisStatus, StatusTable.Status
FROM StatusTable) qryTestx
GROUP BY qryTestx.ThisStatus;
Try this and don't forget to vote ;)
select
count(*),
case
when Status in ( 'sent', 'monitoringStage1', 'monitoringStage2', 'finalApproval') then 'pending'
else status
end as status
from StatusTable
group by
case
when Status in ( 'sent', 'monitoringStage1', 'monitoringStage2', 'finalApproval') then 'pending'
else status
end

Filtering out a unique list containing one specific criteria

I have one table called 'Domains'. Column A (domainnames) contains a list of various domain names. Column B (status) contains it's 'status'. The Status can be either Active,Ended,Blocked,Cancelled. A domain name can can be listed in Column A more than once, and is not limited to having only one type of Status. Note, that if a domain is listed in Column A more than once, and each instance of it has the status Cancelled, all occurrences of that domain should appear in the results.
I want to pull out a list of all domains that 'only' have the status cancelled. They cannot have the status cancelled, AND also another type of status. In this example below, it should return domain5.com only.
Domainnames
Domain1.com
Domain2.com
Domain1.com
Domain4.com
Domain5.com
Status
Active
Ended
Cancelled
Blocked
Cancelled
Many thanks!
SELECT DISTINCT domainname FROM DomainsTable
WHERE
Status = 'Canceled'
You could use a not exists clause to demand that there are no rows for the same domain in another status:
select *
from Domains d1
where status = 'cancelled'
and not exists
(
select *
from Domains d2
where d1.domainname = d2.domainname
and d2.status <> 'cancelled'
)
Try out with following sql query:
select Domainnames from Domains
where Status ='cancelled' AND
Domainnames NOT IN (SELECT Domainnames from Domains where Status <> 'cancelled')
Try this :
select * from domains d
where d.status = 'cancelled' and
( select count(*) from domains where domainnames = d.domainesnames) = 1 ;
If the count equals to 1 that means there is only one row for the d.domainnames and i.e is the current row in the select query.