Trying to count total active, inactive, and specialized memberships - sql

I'm trying to get a count of active vs inactive memberships for classic and basic membership types -- Of the classic memberships, there are a subset of members that signed up through a different company but those memberships would also be considered classic.
So far, I have been able to select all memberships that are either classic or basic and show whether they are active or not. However, I have not had success in COUNTing how many active and inactive memberships there are for each and of the classic memberships, which were done through the different company.
So far, I have this:
SELECT
m.membershipID as MembershipID,
m.Level,
s.subInactive,
CASE
WHEN s.subInactive = 0 THEN s.subInactive + 1
WHEN s.subInactive = 1 THEN s.subInactive - 1
END AS oneMeansActive
FROM dbo.membershipsStartsAndDrops m
INNER JOIN dbo.Subscriptions s on m.membershipID = s.subSubscription_ID
I know I'm probably on the wrong track but would appreciate if someone could point me in the right direction. Thanks!
Sample Data:
membershipID | Level | subInactive | OneMeansActive
1 Classic 0 1
2 Basic 0 1
3 Classic 0 0
Desired Result:
ActClassic | ActBasic | InaClassic | InaBasic | ActSpecial
83079 5607 12658 3403 1270
Columns = Active classic memberships, active basic memberships, inactive classic memberships, inactive basic memberships, active classic memberships that signed up through 3rd party company.
I can't figure out how to count all of these values and also group them like this. I'm pulling data from 2 different databases as well. The classic memberships that signed up through the 3rd party company come from same DB as tbl_subscription. The table it comes from is company_members

You seem to want conditional aggregation. Something like this:
select sum(case when level = 'Classic' then OneMeansActive else 0 end) as numClassicActives,
sum(case when level = 'Basic' then OneMeansActive else 0 end) as numBasicActives,
sum(case when level = 'Classic' then subInactive else 0 end) as numClassicSubinactives,
sum(case when level = 'Classic' then subInactive else 0 end) as numBasicSubinactives
from company_members m

Related

Use auxiliary table to define values for another table's column

I am working with a table that currently uses multiple CASE expressions to define the behavior of one of the columns, i.e.:
SELECT
Employee
,Company
,Department
,Area
,Flag = CASE
WHEN Company = 'Amazon' and Department in ('IT', 'HR')
THEN 0
WHEN Department = 'Legal'
THEN 1
WHEN Area = 'Cloud'
THEN 1
ELSE 0
END
FROM Table1
Which would result in something like the following dummy data:
Employee
Company
Department
Area
Flag
Cindy
Amazon
IT
Support
0
Jack
Amazon
HR
Support
0
Bob
Microsoft
Legal
Contracts
1
Joe
Amazon
Legal
Research
1
Lauren
Google
IT
Cloud
1
Jane
Apple
UX
Research
0
I am trying to simplify the Flag expression by using an auxiliary Mappings table that has the following structure, in order to get the value for the Flag column:
Company
Department
Area
Flag
Amazon
IT
NULL
0
Amazon
HR
NULL
0
NULL
Legal
NULL
1
NULL
NULL
Cloud
1
The NULL values mean the column could take any value. Is it possible to achieve this without falling into multiple CASE statements?

exclude some ids associated to determined condition

In the following code I am looking forward to extract the ids associated to accounts with a determined status.
There are 4 status (Active, Inactive, Closed, Verifying)
Almost every account is associated to a phone and one phone could be associated to various accounts, for example:
A phone could be associated to various accounts, 1 Active, 1 inactive and let's say maybe another closed (lets call this account A).
Account B is only associated to a Closed account
Account C is only associated to an Inactive account
With my code I am looking to identify those phones who are ONLY associated to accounts that are not active. I noticed that my code gives me back all phones associated to accounts like A, B and C (Because A is associated to at least 1 NOT 'Active' account), I just want phones associated to accounts like B and C, and exclude ALL type A (if the phone is linked to at least 1 Active account, I don't want it in my db)
select
phone.id,
phone.number,
account.status as status_account
max(date_trunc('day', accountstatuslog.modified)::date) as modif_account_date
from accountstatuslog
join account on account.id = accountstatuslog.account_id
join phone on phone.id = account.phone_id
where
account.status not in ('Active') and
accountstatuslog.status = account.status and
group by
account.status,
account.phone_id
You can use Anti-Join to eliminate the records that you want.
Anti-Join is efficient because it rejects a row at the first occurrence of the value to eliminate.
Table:
postgres=# select * from PhoneStatus;
phoneaccholder | accountstatus
----------------+---------------
Vincent | Active
Vincent | Inactive
Xavier | Active
Benjamin | Closed
Sebastian | Closed
Gabriel | Active
Christopher | Inactive
(7 rows)
SQL:
SELECT phoneaccholder
,accountstatus
-- ,Count(*)
FROM phonestatus x
WHERE NOT EXISTS (SELECT 1
FROM phonestatus y
WHERE y.accountstatus = 'Active'
AND x.phoneaccholder = y.phoneaccholder)
and accountstatus in ('Closed','Inactive')
GROUP BY accountstatus,
phoneaccholder;
Output:
phoneaccholder | accountstatus
----------------+---------------
Benjamin | Closed
Sebastian | Closed
Christopher | Inactive
(3 rows)

Modifying SELECT query to create Stacked Bar Chart

I have a query for a Placement Application Tracking System which shows the number of students placed and unplaced per programme of study. I'm struggling to create an APEX Stacked Bar Chart out of it, even though the query returns the desired results.
Query:
SELECT programme_name,
SUM(CASE WHEN (cv_approval_date IS NOT NULL AND application_status_id <> 7) OR
application_status_id IS NULL
THEN 1 ELSE 0 END) as Unplaced,
SUM(CASE WHEN (cv_approval_date IS NOT NULL AND application_status_id <> 7) OR
application_status_id IS NULL
THEN 0 ELSE 1 END) as Placed
FROM programme LEFT JOIN
student USING (programme_id) LEFT JOIN
application USING (student_id)
GROUP BY programme_name;
Output:
PROGRAMME_NAME | PLACED | UNPLACED
BSc (Hons) Computer Science | 2 | 2
BSc (Hons) Computing and Games Development | 1 | 0
BSc (Hons) Web Applications Development | 0 | 1
BSc (Hons) Marine Biology and Coastal Ecology | 1 | 0
The graph is supposed to look similar to this - the x axis being Programme, y axis being number of students placed, and unplaced:
http://ruepprich.files.wordpress.com/2011/03/stacked_bar.png?w=550&h=386
How might I go about doing this? Any help would be greatly appreciated!
When creating a chart in Apex you can click on "Chart Query Example" for some sample queries that will work with that chart type.
In the case of a stacked bar chart, the following example is given:
SELECT NULL LINK,
ENAME LABEL,
SAL "Salary",
COMM "Commission"
FROM EMP
ORDER BY ENAME
In your case I think you'll want your query to present the following format:
SELECT NULL LINK,
programme_name AS LABEL,
SUM(...) AS "Unplaced",
SUM(...) AS "Placed"
FROM ...

How to design db for holding Dominion cards?

I'd like to store some information about games of the card game Dominion. You don't need to know much about this game, except that:
There are around 200 unique cards
Each game includes only ten of these cards, or on occasion eleven
I'll be tracking lots more about each game (who played, who won, etc), but what I'm having trouble with is working with the "supply" (the ten included cards for this game).
I'm thinking I want three tables, something like card_name, supply, and game:
card_name supply game
id | name supply | card game | supply | player1 | player2 | ...
----+--------- --------+------ ------+--------+---------+---------+-----
1 | Village 1 | 1 301 | 1 | 'Mike' | 'Tina' | ...
2 | Moat 1 | 3
3 | Witch 1 | 200
... | ... ... | ...
200 | Armory
I think this is a reasonable way to represent "Mike and Tina played a game which contained Village, Witch, Armory, and some other cards I didn't bother typing into this example". Given this structure (or some other one, if you think mine is no good), I'd like to run queries like "which games had Witch and Village, but not Moat?" That is, I want to specify some arbitrary number of "these X cards included, these Y cards excluded" and search the game table for games satisfying the criteria.
I think this is a classic one-to-many relation, where a supply has multiple cards, but I don't understand the right way to search for a supply by multiple cards.
Your data structure is reasonable. I might suggest that you would want a game_users table as well, so the users are not listed in separate columns. This would be particularly important if games had different numbers of users. However, this aspect is not relevant to your question.
You want to solve "set-within-sets" subqueries. Your structure is useful and the supply table provides the basic information needed for this.
So, a query to get the appropriate "supply" records for "Witch", "Village", and not "Moat" would look like:
select supplyid
from supplies s join
cards c
on s.cardid = c.cardid
group by supplyid
having sum(case when cardname = 'Witch' then 1 else 0 end) > 0 and
sum(case when cardname = 'Village' then 1 else 0 end) > 0 and
sum(case when cardname = 'Moat' then 1 else 0 end) = 0;
First note that I changed the name, so the id columns contain the word "id" and the table names are in plural.
Each condition in the having clause is representing one condition on the cards. You can tweak this to get the game information by joining in games:
select g.gameid
from supplies s join
cards c
on s.cardid = c.cardid join
games g
on g.supplyid = s.gameid
group by g.gameid
having sum(case when cardname = 'Witch' then 1 else 0 end) > 0 and
sum(case when cardname = 'Village' then 1 else 0 end) > 0 and
sum(case when cardname = 'Moat' then 1 else 0 end) = 0;

Find Count Distinct in CakePHP

This is a simple query problem. But it seems that I can't get it right :(
I just started using cakephp last week. I'm still playing around exploring. Anyway, here's my problem.
This is the relationship in Model: Product has many Stock. Stock belongs to Product.
This is the sample STOCKS table:
ID | Product Name | Transaction
------------------------------------
1 | Astringent | Purchase
2 | Glutathione | Sales
3 | Glutathione | Sales
I would like to get the number of transaction per product from the STOCKS table.
This is the output I would like with distinct product name:
Transaction | Astringent | Glutathione
--------------------------------------------
purchase | 1 | 0
sales | 0 | 2
Here is a sql query- for exactly what you requested.
SELECT transaction,
SUM(
CASE
WHEN product_name = 'Astringent' THEN 1
ELSE 0
END) AS 'Astringent',
SUM(
CASE
WHEN product_name = 'Glutathione' THEN 1
ELSE 0
END) AS 'Glutathione'
FROM stock
GROUP BY transaction;
However, are you looking for a pivot table i.e., an output with a variable number of columns based on a random number of products? If so, your solution is lot more complicated as a MySQL query, and potentially less complicated as a MySQL and PHP solution. In either case, I think you should share more of your database schema / CakePHP model along with some controller information. In order to render a view with this table is not overly difficult as long as you want Cakephp to output this format.