I have these 2 tables:
Table: Unit
UnitID | Title
1 Unit 1
2 Unit 2
3 Unit 3
Table: Piece
PieceID | UnitID | Category
1 1 A
2 1 A
3 1 B
4 2 A
5 3 B
What I need to do is show a count of the total units containing Piece rows with Category A, as well as the total amount of Piece table rows with Category A (regardless of unitid). So using the data above, the result would be 2 units, 3 Piece rows.
I could do this with two statements, but I would like to do it one.
Any suggestions from craftier folks than I?
Filter out the pieces with the correct category, then count the units distinctly:
select count(distinct UnitId) as Units, count(*) as Pieces
from Piece
where Category = 'A'
Try:
select count(distinct UnitID) total_units, count(*) total_rows
from Piece
where Cateory = 'A';
Related
I'm trying to merge the values of two rows based on the value of another row in a different column. Below is my based table
Customer ID
Property ID
Bookings per customer
Cancellations per customer
A
1
0
1
B
2
10
1
C
3
100
1
C
4
100
1
D
5
20
1
Here is the SQL query I used
select customer_id, property_id, bookings_per_customer, cancellations_per_customer
from table
And this is what I want to see. Any ideas the query to get this would be? We use presto SQL
Thanks!
Customer ID
Property ID
Bookings per customer
Cancellations per customer
A
1
0
1
B
2
10
1
C
3 , 4
100
1
D
5
20
1
We can try:
SELECT
customer_id,
ARRAY_JOIN(ARRAY_AGG(property_id), ',') AS properties,
bookings_per_customer,
cancellations_per_customer
FROM yourTable
GROUP BY
customer_id,
bookings_per_customer,
cancellations_per_customer;
I would like to query a table that has leads assigned by sales rep to return the unique number of leads grouped by agent and also the number sold. There can be multiple leads from one buyer, I would like to select distinct so each buyer is counted only once. Here is the layout of the data:
AgentId
BuyerEmail
Product
Category
1
lisa#gmail.com
Jeans
1
1
lisa#gmail.com
Hat
1
1
ryan#gmail.com
Shoes
3
2
mark#gmail.com
Jeans
1
2
mark#gmail.com
Socks
1
2
mark#gmail.com
Hat
1
4
john#gmail.com
Shirt
3
5
lou#gmail.com
Hat
3
5
tim#gmail.com
Shirt
3
I would like to return a dataset like the following:
AgentId
UniqueLeads
QtySold
1
2
1
2
1
0
4
1
1
5
2
2
I can query this individually but I can't get it to return in one result set. Here are the 2 separate queries:
SELECT COUNT(DISTINCT BuyerEmail) FROM SalesLeads GROUP BY InitialAgent
SELECT COUNT(DISTINCT BuyerEmail) FROM SalesLeads WHERE Category = 3 GROUP BY InitialAgent
How can I query the table and have both data points return in one result set? Please note, a category = 3 means it is sold.
You can use conditional aggregation to calculate QtySold in the same statement:
select AgentId,
count(distinct BuyerEmail) as UniqueLeads,
count(case when Category = 3 then Category end) as QtySold
from SalesLeads
group by AgentId
When Category is anything other than 3 the case statement returns null so that record isn't counted in the QtySold calculation.
db<>fiddle
I have two tables, expenses and categories, they have a many-to-many relationship through the table expenses_categories. I'm trying to implement a filter by categories, lets say that I provided the id for the categories A and B, I want to return the expenses who only have A and B. For example:
Expense X have Category A, B, and C
Expense Y have Category A and B
Expense Z have Category B
I want to return only the Expense Y
I'm using PostgreSQL by the way. I really need to learn how to do this kind of stuff.
Categories
ID
NAME
1
TV
2
CC
3
NET
ExpensesCategories
expense_id
category_id
1
1
1
2
2
1
2
2
2
3
3
1
4
2
I want to get all the Expenses that have ONLY the Categories 1 and 2.
In that case, I expect to only get the Expense 1
expense_id
category_id
1
1
1
2
You can group by expense_id and use STRING_AGG() in the HAVING clause to collect all the category_ids of each expense_id and compare it to a string like '1,2' which contains the category_ids that you want in ascending order as a comma separated list:
SELECT expense_id
FROM ExpensesCategories
GROUP BY expense_id
HAVING STRING_AGG(category_id::text, ',' ORDER BY category_id) = '1,2';
If you want all the rows of these expense_ids in ExpensesCategories, use the above query as a CTE:
WITH cte AS (
SELECT expense_id
FROM ExpensesCategories
GROUP BY expense_id
HAVING STRING_AGG(category_id::text, ',' ORDER BY category_id) = '1,2'
)
SELECT *
FROM ExpensesCategories
WHERE expense_id IN (SELECT expense_id FROM cte);
See the demo.
SQL Table is as follows:
Category | Subcategory |
A 1
A 1
A 2
B 1
B 2
I need the number of each subcategory for each category, not including duplicate subcategories within the category.
You'll notice there are 3 total "1" subcategories, but only a count of 2 as the duplicate is redundant and not included.
Example output:
subcategory | count
1 2
2 2
How can I achieve this? I am familiar with COUNT but I can only get the raw number of rows.
Using Snowflake.
Thanks!
You can use GROUP BY, as in:
select Category, count(distinct Subcategory)
from t
group by Category
I create frequencies on one column in SQL in a standard way.
My code is
select id , count(*) as counts
from TABLE
group by id
order by counts desc
Suppose the output is as follows for six id
id counts
-- -----
1 3 two id have 3 counts per
2 3
---------
3 6 three id have 6 counts per
4 6
5 6
---------
6 2 one id has 2 counts
How can I produce the following?
nid counts
--- ------
1 2
2 3
3 6
I am writing in a hive environment, but that should be standard SQL.
Thanks in advance for answering.
You want two levels of aggregation:
select counts, count(*)
from (select id , count(*) as counts
from TABLE
group by id
) c
group by counts
order by counts;
I call this a "histogram-of-histograms" query. I usually include min(id) and max(id) in the outer select, so I have examples of ids with given frequencies.