Count Distinct Combinations in SQL - sql

Is there a way in SQL to Count the number of occurences of a distict combination of two fields in a table e.g.
categorynum itemnum
1 3
2 1
1 3
1 2
3 1
1 3
and return 3 when counting occurences of (1;3) ?

Sure, just use a regular GROUP BY / COUNT(*)
SELECT categorynum, itemnum, COUNT(*) occurrences
FROM {table}
GROUP BY categorynum, itemnum
If you want a particular combination just add a WHERE clause (before the GROUP BY):
WHERE categorynum = 1 AND itemnum = 3

Related

Merge row values based on other column value

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 need a 3 table join

This is my parent table acc_detial -
ACC_DETIAL example -
acc_id
1
2
3
Now i have 3 tables:
ORDER
EMAIL
REPORT
Each table contains 100 rows and acc_id are ForeignKey from ACC_DETIAL.
In ORDER table I have a columns ACC_ID and QUANTITY. I want the count of ACC_ID and sum of QUANTITY.
ORDER table example:
acc_id
quantity
date
1
2
2022/01/22
2
5
2022/01/23
1
10
2022/01/25
3
1
2022/01/25
In EMAIL table I have a column name ACC_ID and I want count of ACC_ID.
EMAIL table example:
acc_id
mail
date
1
5
2022/01/22
2
10
2022/01/22
1
7
2022/01/23
1
7
2022/01/24
2
10
2022/01/25
In REPORT table I have a columns ACC_ID and TYPE and I want the count of ACC_ID and TYPE. Note that TYPE column has only two, possible values:
postive
negative
I want count of each, i.e. count of postive and count of negative in TYPE column.
REPORT table example:
acc_id
type
date
1
positive
2022/01/22
2
negative
2022/01/22
1
negative
2022/01/23
2
postitive
2022/01/26
2
postitive
2022/01/27
I need to take this in a single i need answer as raw query or sqlalchemy. Is it possible or not? Do I need to write separate query to get each table result ?
Result -
result based on above examplec -
acc_id
total_Order_acc_id
total_Order_quantity
total_Email_acc_id
total_Report_acc_id
total_postitive_report
total_negative_report
1
2
12
3
2
1
1
2
1
5
2
3
2
1
3
1
1
Null
Null
Null
Null
You need to aggregate then join as the following:
SELECT ADL.acc_id,
ORD.ord_cnt AS total_Order_acc_id,
ORD.tot_quantity AS total_Order_quantity,
EML.eml_cnt AS total_Email_acc_id,
RPT.rpt_cnt AS total_Report_acc_id,
RPT.pcnt AS total_postitive_report,
RPT.ncnt AS total_negative_report
FROM ACC_DETIAL ADL LEFT JOIN
(
SELECT acc_id,
SUM(quantity) AS tot_quantity,
COUNT(*) AS ord_cnt
FROM ORDERS
GROUP BY acc_id
) ORD
ON ADL.acc_id = ORD.acc_id
LEFT JOIN
(
SELECT acc_id, COUNT(*) AS eml_cnt
FROM EMAIL
GROUP BY acc_id
) EML
ON ADL.acc_id = EML.acc_id
LEFT JOIN
(
SELECT acc_id,
COUNT(*) AS rpt_cnt,
COUNT(*) FILTER (WHERE type='positive') AS pcnt,
COUNT(*) FILTER (WHERE type='negative') AS ncnt
FROM REPORT
GROUP BY acc_id
) RPT
ON ADL.acc_id = RPT.acc_id
See demo
Sample :
Select
`order`.`acc_id`,
report_email_select.`type`,
report_email_select.report_count,
report_email_select.email_count,
SUM(`quantity`) as quantity_sum
FROM
`order`
Left JOIN(
Select
report_select.`acc_id`,
report_select.`type`,
report_select.report_count,
COUNT(*) as email_count
from
(
SELECT
report.`acc_id`,
report.`type`,
COUNT(*) as report_count
FROM
`report`
WHERE
1
GROUP BY
report.`acc_id`,
report.`type`
) AS report_select
INNER JOIN email ON email.acc_id = report_select.acc_id
GROUP BY
report_select.`acc_id`,
report_select.`type`
) AS report_email_select ON `order`.acc_id = report_email_select.acc_id
GROUP BY
`order`.`acc_id`,
report_email_select.`type`;

SQL left join with 2 or more count group

My table
ID catone cattwo
100 2 1
100 3 1
200 1 2
expect result (count not sum)
ID totalcat1 totalcat2
100 2 2
200 1 1
My query
select COUNT(*) as totalcat1, catone
from Table1
group by cat1
left join
select COUNT(*) as totalcat2, cattwo
from Table1
group by cattwo
Try to have both count columns catone and cattwo
Not sure how to correct it. Thank you
A simple group-by should do it
select ID, COUNT(catone) as totalcat1, COUNT(cattwo) as totalcat2
from Table1
group by ID;
Note that this simply counts the number of values that are not NULL. If your original data was this...
ID catone cattwo
100 2 1
100 3 1
100 4 NULL
... then the result would be
ID totalcat1 totalcat2
100 3 2
If you want to count the distinct values - so totalcat2 would be 1 (as only 1 value exists in that column, although it's there twice) you could use
select ID, COUNT(DISTINCT catone) as totalcat1, COUNT(DISTINCT cattwo) as totalcat2
from Table1
group by ID;
which would return totalcat1 = 3 and totalcat2 = 1.
Here's a db<>fiddle with the two options.
Here's a second db<>fiddle on request of OP with ID 200.

What is the proper way to complete cross-tab on the following segment in SQL?

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.

SQL Show value that appears more times and how many times

I'm trying to show the value that appears more times from a movies table.
For example:
movie_id, tag_id, score
1 1 4
1 3 5
2 1 3
3 2 4
3 3 5
Result:
tag_id, times
1 2
3 2
2 1
That table has the following columns: {movie-id, tag-id, score}.
How I can retrieve the tag-id that appears more times and how many times?
I've tried the following but it shows the same number for each tag-id:
SELECT tagId, COUNT(tagId) AS ocurrence FROM scores GROUP BY tagId ORDER BY ocurrence DESC
I think you're looking for:
SELECT TAGID, COUNT(TAGID)
FROM TABLENAME
GROUP BY TAGID
ORDER BY COUNT(TAGID)
--or you could do a having clause where COUNT(TAG-ID) > 1
SELECT tagId, COUNT(tagId) FROM scores GROUP BY (tagID) HAVING COUNT(tagId) >= ALL
(SELECT COUNT(tagId) FROM scores GROUP BY (tagId))
This will also work.