Join Count and Sum Queries into Single Dataset - sql-server-2008-r2

Is it possible to somehow join the following two queries into a single dataset that can be used in tablix in an SSRS report?
Table Policy
------------
PolNum
SubmitDate
ProdID
Pend
Table Product
-------------
ProdID
ProdCat
Table Prem
---------
PolNum
Prem
Query 1
Select Count(PolNum), DATEPART(wk, SubmitDate)
From Policy INNER JOIN Product on Policy.ProdID = Product.ProdID
Where (year(SubmitDate) = year(getdate()))
Group by ProdCat, SubmitDate
Query2
Select sum(Prem), DATEPART(wk, SubmitDate)
From Policy INNER JOIN Product on Policy.ProdID = Product.ProdID INNER JOIN
Prem on Pol Pol.PolNum = Prem.PolNum
Where (Pend = 1)
Group By ProdCat, SubmitDate
The final report would look something like this:
Cat1 Cat2 Cat3 PremCat1 PremCat2 Premcat3
Week 1 5 4 5 65 25 95
Week 2 2 5 6 45 10 65
Week 3 3 6 15 13 15 96
Week 4 5 7 13 98 45 35
I've tried using a derived table, but the results aren't correct because The Pend flag will filter out some of the results for the count. I've read some about Common Table Expressions, but I do not fully understand when they would be used of how to use them. Any help on this would be greatly appreciated.

Why don't you just join them?
select * from
(Select Count(PolNum) as PolCount, DATEPART(wk, SubmitDate) t1week
From Policy INNER JOIN Product on Policy.ProdID = Product.ProdID
Where (year(SubmitDate) = year(getdate()))
Group by ProdCat, SubmitDate) as t1
inner join
(Select sum(Prem) as sumPrem, DATEPART(wk, SubmitDate) t2week
From Policy INNER JOIN Product on Policy.ProdID = Product.ProdID INNER JOIN
Prem on Pol Pol.PolNum = Prem.PolNum
Where (Pend = 1)
Group By ProdCat, SubmitDate) as t2
on t1.t1week = t2.t2week

Related

Postgresql group by relation

I want to group the records by relation.
products table:
id
price
1
100
2
200
3
300
4
400
product_properties table:
id
productId
propertyId
1
1
2
2
1
3
3
2
2
4
2
3
5
3
4
6
4
4
The query should select lowest price group by product_properties. I mean, If products have same properties in product_properties, query should return product that has lowest price.
So, For these tables query should return products that have ids 1,3.
I use TypeORM, I tried join the relation and distinct on relation alias name but its not worked.
How can I achieve this?
I wrote two variants query for you:
-- variant 1
select distinct t1.product_id from (
select
pr.price, pp.product_id, pp.property_id, min(pr.price) OVER(PARTITION BY pp.property_id) as min_price
from
test.product_properties pp
inner join
test.products pr on pp.product_id = pr.id
) t1
where
t1.price = t1.min_price;
-- variant 2
select distinct t1.product_id from test.product_properties t1
inner join test.products t2 on t1.product_id = t2.id
inner join (
select
pp.property_id, min(pr.price) as min_price
from
test.product_properties pp
inner join
test.products pr on pp.product_id = pr.id
group by pp.property_id
) t3 on t3.property_id = t1.property_id and t3.min_price = t2.price;

How to calculate values from previous month to current month

I want to calculate this table. Everytime that there is a new participant per month it will add the previous value to current value.
month
no_participant
2021-01
10
2021-02
20
2021-03
5
2021-04
17
Something like this, output
month
no_participant
count
2021-01
10
10
2021-02
20
30
2021-03
5
35
2021-04
17
52
Here's my query: I am using Postgres. Thanks to your help
SELECT (TO_CHAR(CSD.SCHEDULED_START_DATETIME, 'YYYY-MM'))AS MONTH,
COUNT(DISTINCT PARTICIPANT_ID) AS PARTICIPANT
FROM TSUP.COURSE_SCHEDULE_DETAIL AS CSD
INNER JOIN TSUP.COURSE_PARTICIPANT AS CP
ON CSD.COURSE_SCHEDULE_ID = CP.COURSE_SCHEDULE_ID
INNER JOIN(
SELECT
MIN(COALESCE(CSD.RESCHEDULED_START_DATETIME, CSD.SCHEDULED_START_DATETIME)) AS SCHEDULED_START_DATETIME,
MAX(COALESCE(CSD.RESCHEDULED_END_DATETIME, CSD.SCHEDULED_END_DATETIME)) AS SCHEDULED_END_DATETIME,
COUNT(CSD.SCHEDULED_START_DATETIME) AS "COUNT"
FROM TSUP.COURSE_SCHEDULE_DETAIL AS CSD
INNER JOIN (
SELECT CP.PARTICIPANT_ID AS "PARTICIPANT",
MIN(COALESCE(CSD.RESCHEDULED_START_DATETIME, CSD.SCHEDULED_START_DATETIME)) AS SCHEDULED_START_DATETIME,
MAX(COALESCE(CSD.RESCHEDULED_END_DATETIME, CSD.SCHEDULED_END_DATETIME)) AS SCHEDULED_END_DATETIME
FROM TSUP.COURSE_PARTICIPANT AS CP
INNER JOIN TSUP.COURSE_SCHEDULE_DETAIL AS CSD
ON CP.COURSE_SCHEDULE_ID = CSD.COURSE_SCHEDULE_ID
INNER JOIN TSUP.COURSE_SCHEDULE AS CS
ON CSD.ID = CS.ID
INNER JOIN TSUP.COURSE AS C
ON CS.COURSE_ID = C.ID
INNER JOIN TSUP.COURSE_CATEGORY AS CC
ON C.COURSE_CATEGORY_ID = CC.ID
INNER JOIN TSUP.EMPLOYEE AS E
ON CP.PARTICIPANT_ID = E.ID
INNER JOIN TSUP.MEMBER_ROLE AS MR
ON E.MEMBER_ROLE_ID = MR.ID
WHERE C.MANDATORY = 'Yes'
AND MR.ROLE_TYPE = 'Dev'
AND CC.CATEGORY = 'JJ'
GROUP BY CP.PARTICIPANT_ID)
TEMP ON CSD.SCHEDULED_START_DATETIME = TEMP.SCHEDULED_START_DATETIME
GROUP BY CSD.RESCHEDULED_START_DATETIME, CSD.SCHEDULED_START_DATETIME,
CSD.RESCHEDULED_END_DATETIME, CSD.SCHEDULED_END_DATETIME
)
TEMP ON CSD.SCHEDULED_START_DATETIME = TEMP.SCHEDULED_START_DATETIME
GROUP BY MONTH
The query you provided is verbose, and also does not seem to exactly line up with the sample data. I will give the following query based on the sample data shown:
SELECT month, no_participant, SUM(no_participant) OVER (ORDER BY month) AS count
FROM yourTable
ORDER BY month;
The above logic uses SUM() as an analytic function.

How to simplify a join of 2 tables in HIVE and count values

I have two tables in HIVE, "orders" and "customers". I want to get top n user names of users who placed most orders (in status "CLOSED"). Orders table has key order_customer_id, column order_status and customers has key customer_id and name consists of 2 columns customer_fname and customer_lname.
ORDERS
order_customer_id, order_status
1,CLOSED
2,CLOSED
3,INPROGRESS
1,INPROGRESS
1,CLOSED
2,CLOSED
CUSTOMERS
customer_id, customer_fname, customer_lname
1,Mickey, Mouse
2,Henry, Ford
3,John, Doe
I tried this code:
select c.customer_id, count(o.order_customer_id) as COUNT, concat(c.customer_fname," ",c.customer_lname) as FULLNAME from customers c join orders o on c.customer_id=o.order_customer_id where o.order_status='CLOSED' group by c.customer_id,FULLNAME order by COUNT desc limit 10;
this does not work - returns error.
I was able to get the result by first creating a 3rd table:
create table id_sum as select o.order_customer_id,count(o.order_id) as COUNT from orders o join customers c on c.customer_id=o.order_customer_id where order_status='CLOSED' group by o.order_customer_id;
1833 6
5493 5
1363 5
1687 5
569 4
1764 4
1345 4
Then I joined the tables:
select s.*,concat(c.customer_fname," " ,c.customer_lname) from id_sum s join customers c on s.order_customer_id = c.customer_id order by count desc limit 20;
This resulted in desired output:
customer_id, order_count, full_name
1833 6 Ronald Smith
5493 5 Mary Cochran
1363 5 Kathy Rios
1687 5 Jerry Ellis
569 4 Mary Frye
1764 4 Megan Davila
1345 4 Adam Wilson
Is there a way how to write it in one command or more effectively?
The subquery with alias sq creates a relation with two columns order_count and customer_id calculating for each customer_id the total number of orders. This is then joined with the CUSTOMERS table. The result is sorted descending and limited to (the top) 10 rows.
SELECT c.customer_id, sq.order_count, concat(c.customer_fname," " ,c.customer_lname) as full_name
FROM CUSTOMERS c JOIN (
SELECT COUNT(*) as order_count, order_customer_id FROM ORDERS
WHERE order_status = 'CLOSED'
GROUP BY order_customer_id
) sq on c.customer_id = sq.order_customer_id
ORDER BY sq.order_count desc LIMIT 10
;
The idea is to use a subquery instead of a third table.

Postgres how to maintain order of rows using CTEs

I have 2 tables
students:
id | name | age
1 abc 20
2 xyz 21
scores:
id | studentid | marks
1 1 20
2 2 22
3 2 20
4 1 22
5 1 20
where studentid is foreign key to students table
When a do
select studentid
from scores
where marks=20;
I get the following result
1, 2, 1
But if want the name of the student name and when I do a join using
select t1.name
from students t1
inner join scores t2 on t1.id = t2.studentid
where t2.marks=20;
I get xyz,abc,abc Though the ouput is correct is there any way I can maintain the order in which scores are listed in the scores table? I should get abc,xyz,abc as output. I tried using subquery as well
SELECT name
FROM students
WHERE ID IN ( select studentid from scores where marks=20) ;
but that also did not give me correct order. How can this be achieved using CTEs (common table expressions)? I tried the follownig cte but it did not work
with cte as(
select t2.id, t1.name
from students t1
inner join scores t2 on t1.id = t2.studentid
where t2.marks=20)
select name from cte order by id
You can order by a column not present in select list:
select t1.name
from students t1
inner join scores t2 on t1.id = t2.student_id
where t2.marks=20
order by t2.id;
name
------
abc
xyz
abc
(3 rows)

DB2 query group by id but with max of date and max of sequence

My table is like
ID FName LName Date(mm/dd/yy) Sequence Value
101 A B 1/10/2010 1 10
101 A B 1/10/2010 2 20
101 X Y 1/2/2010 1 15
101 Z X 1/3/2010 5 10
102 A B 1/10/2010 2 10
102 X Y 1/2/2010 1 15
102 Z X 1/3/2010 5 10
I need a query that should return 2 records
101 A B 1/10/2010 2 20
102 A B 1/10/2010 2 10
that is max of date and max of sequence group by id.
Could anyone assist on this.
-----------------------
-- get me my rows...
-----------------------
select * from myTable t
-----------------------
-- limiting them...
-----------------------
inner join
----------------------------------
-- ...by joining to a subselection
----------------------------------
(select m.id, m.date, max(m.sequence) as max_seq from myTable m inner join
----------------------------------------------------
-- first group on id and date to get max-date-per-id
----------------------------------------------------
(select id, max(date) as date from myTable group by id) y
on m.id = y.id and m.date = y.date
group by id) x
on t.id = x.id
and t.sequence = x.max_seq
Would be a simple solution, which does not take account of ties, nor of rows where sequence is NULL.
EDIT: I've added an extra group to first select max-date-per-id, and then join on this to get max-sequence-per-max-date-per-id before joining to the main table to get all columns.
I have considered your table name as employee..
check the below thing helped you.
select * from employee emp1
join (select Id, max(Date) as dat, max(sequence) as seq from employee group by id) emp2
on emp1.id = emp2.id and emp1.sequence = emp2.seq and emp1.date = emp2.dat
I'm a fan of using the WITH clause in SELECT statements to organize the different steps. I find that it makes the code easier to read.
WITH max_date(max_date)
AS (
SELECT MAX(Date)
FROM my_table
),
max_seq(max_seq)
AS (
SELECT MAX(Sequence)
FROM my_table
WHERE Date = (SELECT md.max_date FROM max_date md)
)
SELECT *
FROM my_table
WHERE Date = (SELECT md.max_date FROM max_date md)
AND Sequence = (SELECT ms.max_seq FROM max_seq ms);
You should be able to optimize this further as needed.