SQL - How to Count from multiple tables and add them together - sql

I am trying to do a count from multiple tables but there could be multiple entries in each table. Here is simple sample data simplified. There are actually more then 3 tables but just so I get an understanding of how to do it
table2 table2 table3
person_ID person_id person_id
1 1 2
2 1 2
3 2 1
4 2 4
5 4 5
I'm trying to get a count of each person ID in each table so the output would be the following. Note that personID is a key I don't need the addition of the number of the ID not 2+2+2+2. But the count of the number of appearances it makes in the all tables then the count in each table added together for total number of appearances it makes. Basically I'm trying to find a total number of items attached to each personID
person_id total
1 4
2 4
3 1
4 3
5 2

Select the ids from all the tables together withunion. That result can be grouped by the id and counted for each
select person_id, count(*) as count
from
(
select person_id from table1
union all
select person_id from table2
union all
select person_id from table3
) tmp
group by person_id

Related

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`;

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.

sum of 2 different columns in MSSQL

I have 2 tables A and B. The columns names are similar in both the tables. The columns are
1. fees
2. user_id
I want to get the sum of fees from both tables where user_id = 1
For eg:
Table A:
id user_id fees
1 1 10
2 2 11
3 1 5
Table B:
id user_id fees
1 1 15
2 2 10
3 1 20
I need the result as below:
user_id fees
1 50
2 21
Please help me with the query
Try this:
select user_id, sum(fees) from (
select user_id, fees from Table_A
union all
select user_id, fees from Table_B
) as A
group by user_id

How to sort a column in one table based on the rank in another table

I have a table Table 1 that has User_ID and Item_List where items are arranged randomly
Customer_id Item_List
22 1,4,3,2
24 6,3,2,1
23 4,5,7,8
Table 2 has the ranks of the item according to the highest value
Item_Id Item_Rank
1 8
2 5
3 3
4 4
5 2
6 7
7 1
8 6
I want to produce a Table that has Customer_id with the corresponding Item List ranked according to the Item Rank in Table 2
Customer_id Ranked_Item_List
22 3,4,2,1
24 3,2,6,1
23 7,5,4,8
I don't know any efficient method to do it in hive. Any suggestions?
I can think in 2 different ways, create your UDF to avoid the explode or
select customer_id, collect_list(item_id) from (
select customer_id, item_id, item_rank from
table1 lateral view inline(item_list) item_id join
table2 on table1.item_id = table2.item_id --this should be done as mapjoin if your rank table is not big
) distributed by customer_id, sort by item_rank;
Like I said before, depending on the size of your data, you could create an UDF to apply the sort at mapper level based on your lookup table

SQL - Order by amount of occurrences

It's my first question here so I hope I can explain it well enough,
I want to order my data by amount of occurrences in the table.
My table is like this:
id Daynr
1 2
1 4
2 4
2 5
2 6
3 1
4 2
4 5
And I want it to sort it like this:
id Daynr
3 1
1 2
1 4
4 2
4 5
2 4
2 5
2 6
Player #3 has one day in the table, and Player #1 has 2.
My table is named "dayid"
Both id and Daynr are foreign keys, together making it a primary key
I hope this explains my problem enough, Please ask for more information it's my first time here.
Thanks in advance
You can do this by counting the number of times that things occur for each id. Most databases support window functions, so you can do this as:
select id, daynr
from (select t.*, count(*) over (partition by id) as cnt
from table t
) t
order by cnt, id;
You can also express this as a join:
select t.id, t.daynr
from table as t inner join
(select id, count(*) as cnt
from table
group by id
) as tg
on t.id = tg.id
order by tg.cnt, id;
Note that both of these include the id in the order by. That way, if two ids have the same count, all rows for the id will appear together.