sum of sales per postal code group - sql

I have a query where you can see all the sales of a person divided in postal groups. But now I want to have the sum of all the sales per postal group.
I have the query like this:
SELECT
p.LastName,
ROW_NUMBER() OVER (PARTITION BY PostalCode
ORDER BY SUM(s.SalesYTD) DESC) AS 'Row Number',
CAST(s.SalesYTD AS INT) SalesYTD,
a.PostalCode
FROM
Sales.SalesPerson s
INNER JOIN
Person.Person p ON s.BusinessEntityID = p.BusinessEntityID
INNER JOIN
Person.Address a ON a.AddressID = p.BusinessEntityID
GROUP BY
p.LastName, a.PostalCode,s.SalesYTD;
--WHERE TerritoryID IS NOT NULL
--AND SalesYTD <> 0
But how to manage the total of each postal group?
Thank you
This is the ouput:
LastName Row Number SalesYTD PostalCode
Mitchell 1 4251369 98027
Blythe 2 3763178 98027
Carson 3 3189418 98027
Reiter 4 2315186 98027
Vargas 5 1453719 98027
Ansman-Wolfe 6 1352577 98027
Jiang 7 559698 98027
Pak 1 4116871 98055
Varkey Chudukatil 2 3121616 98055
Saraiva 3 2604541 98055
Ito 4 2458536 98055
Valdez 5 1827067 98055
Mensa-Annan 6 1576562 98055
Campbell 7 1573013 98055
Tsoflias 8 1421811 98055
Alberts 9 519906 98055
Abbas 10 172524 98055
So how to get the total of salesYTD of postal code: 98027?
Thank you

To get sales per postal code just:
SELECT PostalCode, SUM(SalesYTD) AS 'Summary sales'
FROM Sales.SalesPerson s
INNER JOIN Person.Person p ON s.BusinessEntityID = p.BusinessEntityID
INNER JOIN Person.Address a ON a.AddressID = p.BusinessEntityID
GROUP BY a.PostalCode
If you want sales of particular PostalCode you can even do it that way:
SELECT SUM(SalesYTD) AS 'Summary sales'
FROM Sales.SalesPerson s
INNER JOIN Person.Person p ON s.BusinessEntityID = p.BusinessEntityID
INNER JOIN Person.Address a ON a.AddressID = p.BusinessEntityID
WHERE PostalCode = 98027

Related

Oracle left join with conditions from the target table

I have two tables Customers, Sales like below:
Customers :
id
first_name
last_name
gender
age
customer_since
1
Daniel
Black
M
34
2014-10-13
2
Erik
Brown
M
25
2015-06-10
3
Diana
Trump
F
39
2015-10-25
4
Anna
Yao
F
19
2017-02-20
5
Christian
Sanders
M
42
2018-01-31
Sales:
id
date
book_id
customer_id
quantity
amount
1
2019-09-02
2
3
1
14.99
2
2019-10-01
1
2
1
12.99
3
2019-10-01
3
4
1
15.75
I need to get all customers and their data in sales table even if they don't have records in sales table so I did left join like below :
SELECT c.id as customer_id, c.first_name, c.last_name, c.gender, c.age, c.customer_since,
s.sdate AS sales_date, s.id as sale_id
FROM customers c
LEFT JOIN sales s
ON c.id = s.customer_id
and I got this result:
CUSTOMER_ID
FIRST_NAME
LAST_NAME
GENDER
AGE
CUSTOMER_SINCE
SALES_DATE
SALE_ID
3
Diana
Trump
F
39
25-OCT-15
02-SEP-19
1
2
Erik
Brown
M
25
10-JUN-15
01-OCT-19
2
1
Daniel
Black
M
34
13-OCT-14
-
-
4
Anna
Yao
F
19
20-FEB-17
-
-
5
Christian
Sanders
M
42
31-JAN-18
-
-
which is expected my question is what if I need to get all customers that only in the source table and customers from the target table which has specific condition I run the below query
SELECT c.id as customer_id, c.first_name, c.last_name, c.gender, c.age, c.customer_since,
s.sdate AS sales_date, s.id as sale_id
FROM customers c
LEFT JOIN sales s
ON c.id = s.customer_id
where s.id=1
and I got only one record like this
CUSTOMER_ID
FIRST_NAME
LAST_NAME
GENDER
AGE
CUSTOMER_SINCE
SALES_DATE
SALE_ID
3
Diana
Trump
F
39
25-OCT-15
02-SEP-19
1
but I need this result
CUSTOMER_ID
FIRST_NAME
LAST_NAME
GENDER
AGE
CUSTOMER_SINCE
SALES_DATE
SALE_ID
3
Diana
Trump
F
39
25-OCT-15
02-SEP-19
1
1
Daniel
Black
M
34
13-OCT-14
-
-
4
Anna
Yao
F
19
20-FEB-17
-
-
5
Christian
Sanders
M
42
31-JAN-18
-
-
What should I do?
You need to move the criteria from the WHERE clause of the second query to the ON clause of the join:
SELECT c.id as customer_id, c.first_name, c.last_name, c.gender, c.age,
c.customer_since, s.sdate AS sales_date, s.id AS sale_id
FROM customers c
LEFT JOIN sales s
ON c.id = s.customer_id AND s.id = 1;
By restricting the sales ID in the WHERE clause, you filter off any non matching records. By moving this restriction to the join, all records would be retained, but NULL values would appear for all non matching sales fields.

Query to get grandparents and grandkids

I got a table people:
ID name surname mother_id father_id
--------------------------------------------
1 John smith null null
2 kate m null null
3 philip smith 2 1
4 dimitr smith 7 3
etc.
I tried this query.
SELECT
p.name, P.surname,
c.name as 'Mothers name', c.surname as 'Mothers surname',
gm.name as 'Grandmother name', gm.surname as 'Grandmother surname'
FROM
dbo.people AS p
JOIN
dbo.people AS c ON (c.mother = p.Id)
JOIN
dbo.people AS gm ON (gm.mother = c.Id)
But it doesn't really return what I expected
Problem with ON clause :
select p.name, p.surname,
coalesce(pm.name, '') as mothername, coalesce(pm.surname, '') as mothersurname,
coalesce(pf.name, '') as grandmothername,
coalesce(pf.surname, '') as grandmothersurname
from people p left join
people pm
on pm.id = p.mother_id left join -- use mother_id from people p
people pf
on pf.id = p.father_id; -- use father_id from people p;
Here is db-fiddle.

How to join 2 tables with select and count in single query

I need to join 2 tables (Person and PersonLine). The result should contain id and name column from Person table and count of personlineid column from PersonLine Table for each id. But sql query returns count of all personlineid. Can anyone help to form the sql.
Person:
ID NAME AGE
100 John 25
101 James 30
102 Janet 35
PersonLine:
ID NAME PERSONLINEID
100 John 1
100 John 2
100 John 3
101 James 1
101 James 2
102 Janet 1
SQL:
SELECT P.ID, CNT.COUNT_PERSONLINE, P.NAME
FROM PERSON P
LEFT JOIN PERSONLINE PL
ON P.ID = PL.ID,
(SELECT count(PL.PERSONLINEID) cnt FROM PERSON P LEFT JOIN PERSONLINE PL ON P.ID = PL.ID WHERE
P.ID = PL.ID) cnt
JOIN Table (Expected):
ID COUNT_PERSONLINE NAME
100 3 John
101 2 James
102 1 Janet
JOIN Table (Actual):
ID COUNT_PERSONLINE NAME
100 6 John
101 6 James
102 6 Janet
With your sample data, you don't even need the Person table -- because you seem to have redundant table in the two tables. You should probably fix this, but:
select pl.id, pl.name, count(*)
from personline pl
group by pl.id, pl.name;
Your count is just counting all the rows from the join of the tables -- that would be all the rows. A simple aggregation should suffice, even if you decide that the join is still necessary.
EDIT:
You have several choices with lots of columns in persons. One method is to put them in the group by:
select pl.id, pl.name, p.col1, p.col2, count(*)
from persons p join
personline pl
on p.id = pl.id
group by pl.id, pl.name, p.col1, p.col2
Another method is to do the aggregation before the join:
select p.*, pl.cnt
from person p join
(select pl.id, pl.name, count(*) as cnt
from personline pl
group by pl.id, pl.name
) pl
on p.id = pl.id;
Or, a correlated subquery:
select p.*, (select count(*) from personline pl where p.id = pl.id)
from person;

Group Join between three tables to get the percentage

I have three tables Attendance, Employee, Sector
Employee Table
EmiId -Name -SectorId
123 ABC 1
231 BCD 2
125 WER 1
Attendance
AttId -EmpId -Dt
1 123 12/12/2014 9:00
2 231 12/12/2014 10:00
Sector
SectorId -SectorName
1 North Sector
2 East Sector
my query is
SELECT COUNT(Attendance.Emp_Id) as AttCount,(select COUNT(*) from Employee) as EmpCount
FROM Employee INNER JOIN
Sector ON Employee.SectorId = Sector.SectorId INNER JOIN
Attendance ON Employee.EmpId = Attendance.EmpId
group by Sector.SectorId
and i keep getting same number of employees for both instead so the (select COUNT(*) from Employee)- EmpCount seems to be incorrect.I keep getting the same number for both the sectors. Although the Attcount seems to work fine.
Please help. Thanks in advance.
You just making select count from the same table - do not expect other results.
Perhaps someone could do it better
SELECT COUNT(Attendance.Emp_Id),COUNT(case when Employee.empid=attendance.attid then 1 else 0 end)
FROM Employee JOIN Sector ON Employee.SectorId = Sector.SectorId
LEFT JOIN Attendance ON Employee.EmpId = Attendance.Emp_Id
group by Sector.SectorId
Maybe you need LEFT JOIN with Attendance
SELECT COUNT(Attendance.Emp_Id),(select COUNT(*) from Employee)
FROM Employee JOIN Sector ON Employee.SectorId = Sector.SectorId
LEFT JOIN Attendance ON Employee.EmpId = Attendance.EmpId
group by Sector.SectorId

AdventureWorks Query

In AdventureWorks 2008, what are some other (better) ways of writing this query:
SELECT DISTINCT o.CustomerID, c.CustomerType,
ISNULL(s.Name, p.FirstName + ' ' + p.LastName) AS Name
FROM Sales.SalesOrderHeader o
INNER JOIN Sales.Customer c
ON c.CustomerID = o.CustomerID
LEFT OUTER JOIN sales.Individual i
ON i.CustomerID = o.CustomerID
LEFT OUTER JOIN sales.Store s
ON s.CustomerID = o.CustomerID
LEFT OUTER JOIN Person.Contact p
ON p.ContactID = i.ContactID
ORDER BY CustomerID
Preferably with the ability to support additional CustomerTypes.
Results look like:
CustomerID CustomerType Name
697 S Brakes and Gears
698 S Western Bike Supplies
699 S Sensational Discount Store
700 S Underglaze and Finish Company
701 S Future Bikes
11000 I Jon Yang
11001 I Eugene Huang
11002 I Ruben Torres
11003 I Christy Zhu