I need a 3 table join - sql

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

Related

Select rows with max date from table

I have such table and need table 2 result. I am trying to select rows with max date grouped by project_id and ordered by id. And result table must have id column. Tried such request:
SELECT MAX(charges.id) as id,
"charges"."profile_id", MAX(failed_at) AS failed_at
FROM "charges"
GROUP BY "charges"."profile_id"
ORDER BY "charges"."id" ASC
And have error:
ERROR: column "charges.id" must appear in the GROUP BY clause or be used in an aggregate function)
Example table
id
profile_id
failed_at
1
1
01.01.2021
2
1
01.02.2021
3
1
01.03.2021
4
2
01.06.2021
5
2
01.05.2021
6
2
01.04.2021
Needed result
id
profile_id
failed_at
3
1
01.03.2021
4
2
01.06.2021
SELECT charges.*
FROM charges
INNER JOIN
(
SELECT
profile_id,
MAX(charges.failed_at) AS MaxFailed_at
FROM charges
GROUP BY profile_id
) AS xQ ON charges.profile_id = xQ.profile_id AND charges.failed_at = xQ.MaxFailed_at

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.

Remove Duplicate Records in Hive

I want to create a table that indicates medical providers that are linked by common members. For example, if I go to prov 1 and prov 2, then prov 1 and prov 2 will be linked because I visited both.
I have a table where each record indicates a member visiting a provider on a specific date. The table contains millions of members and thousands of provs. Below is a small example of the table:
member prov date
1 1 1/1/15
1 2 1/2/15
2 16 1/12/14
2 5 1/1/16
I am trying to create a table where each record indicates two distinct providers being linked by a common member. For example:
member prov1 prov2 date1 date2
1 1 2 1/1/15 1/2/15
2 16 5 1/12/14 1/1/16
I am trying to use an inner join on the same table, but it is returning duplicate records. I thought the distinct clause would fix this, but it does not seem to get the job done. My query is shown below:
select distinct a.member, a.prov, b.prov, a.date, b.date
from table1 as a
inner join table1 as b
on a.member=b.member
This query returns distinct records, but there are records that contain the same information. Below shows an example of this:
a.member a.prov b.prov a.date b.date
1 1 2 1/1/15 1/2/15
1 2 1 1/2/15 1/1/15
Above we see that the records are distinct, but they describe the same information. Below is what I want the query to return:
a.member a.prov b.prov a.date b.date
1 1 2 1/1/15 1/2/15
How can I alter the above query so that I only return distinct information? I don't want 1 record per member. I want 1 record for each distinct prov pairings by member.
One option is to use conditional aggregation with a subquery using row_number:
select member,
max(case when rn = 1 then prov end) prov1,
max(case when rn = 2 then prov end) prov2,
max(case when rn = 1 then date end) date1,
max(case when rn = 2 then date end) date2
from (select member,
prov,
date,
row_number() over (partition by member order by prov, date) rn
from table1) t
group by member

How to apply a single query that sum column for individual values

I have 2 tables named user and statistics
user table has 3 columns: id, name and category
statistics table has 3 columns: id, idUser (relational), cal
something like this:
user
Id name category
1 name1 1
2 name2 2
3 name3 3
statistics
Id idUser cal
1 1 1
2 1 1
3 1 1
4 2 1
5 2 1
How can I apply a query that sum the cal column by each category of users and give me something like this:
category totalcal
1 3
2 2
3 0
You want to do a left join to keep all the categories. The rest is just aggregation:
select u.category, coalesce(sum(s.cal), 0) as cal
from users u left join
statistics s
on u.id = s.idUser
group by u.category;
Use LEFT JOIN to get 0 sum for the category=3:
SELECT
user.category
,SUM(statistics.cal) AS totalcal
FROM
user
LEFT JOIN statistics ON statistics.idUser = user.Id
GROUP BY
user.category
Here SUM would return NULL for category=3. To get 0 instead of NULL you can use COALESCE(SUM(statistics.cal), 0).

Microsoft SQL - Counting total of matching values in other table

I have a SQL data scructure like this.
Table 1
http://pbrd.co/1x6TAl3
Table 2
http://pbrd.co/1x6TIRw
I'm trying to count the number of times each item_num has been sold based on the item_qty value in the second table.
Each item_num can appear multiple times in the second table.
I need a way to add the total item_qty for each associated item_num and output it to show how many times an item has been sold.
The correct output ordering by total quantity sold in descending order should look like this.
item_num: 4 7 6
qty_sold: 11 5 4
Try this:
SELECT
a.item_num
, SUM(b.item_qty) as "qty_sold"
FROM
Table1 a
LEFT JOIN
Table2 b
ON a.item_num = b.item_num
GROUP BY
a.item_num
ORDER BY
qty_sold DESC
SELECT A.Item_num , A.Item_name , sum(B.Item_Qty) from Table1 as A inner join Table2 as B
on A.Item_num=B.Item_num
group by A.Item_num , A.Item_name
result:
item_num item_name Item_qty
1 A 1
2 B 1
4 D 11
6 F 4
7 G 5