Group by and Pivot functions giving different counts - sql

Group by and Pivot operations give different counts.
I used Group by to get count of vehicles by City and used Pivot to get count of vehicles by Make.
SELECT MAKE, [AMB],[BNG],[CBE],[GBM],[KKE],[OMR],[PDR]
FROM
(
SELECT MAKE, BRANCH, COUNT(DISTINCT [VEH NO]) [VEHICLE COUNT]
FROM MAKE_MODEL_DESCRIPTION
GROUP BY MAKE, BRANCH
) X
PIVOT
(
SUM([VEHICLE COUNT]) FOR BRANCH IN ([AMB],[BNG],[CBE],[GBM],[KKE],
[OMR],[PDR])
) AS PVT
The total count I get for above Pivot query is 150.
select BRANCH, COUNT(distinct [VEH NO])
from MAKE_MODEL_DESCRIPTION
group by BRANCH
The total count I get for above GROUP BY query is 140.
Shouldn't both the same number given they are from same data source?
Can someone let me know where I am going wrong.

No, you should not expect the counts to be the same. The GROUP BY is counting distinct vehicles over all makes. The PIVOT is counting distinct vehicles only within a single branch and model.
In other words, the same vehicle might be in different branches.
If you include the make, then the numbers should be the same:
select MAKE, BRANCH, COUNT(distinct [VEH NO])
from MAKE_MODEL_DESCRIPTION
group by MAKE, BRANCH

Related

How to calculate average using case when and distinct count?

My source table contains sales information. Each row is a person and records every time they've shopped/where. I can therefore calculate the average transaction value per industry by the following:
select
industry,
COALESCE(AVG(CASE WHEN shopcode in (1,2,4) THEN dollar END), 0) AS avt
from sales
group by industry
But how can I adapt this to calculate the spend per distinct count of user i.e.: sum(dollar)/count(distinct person) so similar to above but instead of sum/count(*) sum/count(distinct person)... I need to use coalesce with this as well.
how can i adapt this to calculate the spend per distinct count of user i.e.: sum(dollar)/count(distinct person)
You can use:
select industry,
sum(dollar) / count(distinct person)
from sales
group by industry;
I'm not sure what the filtering on shop_code is for. It is in your query but not part of the question. If you want this for particular shops, I would suggest moving this to a where clause:
select industry,
sum(dollar) / count(distinct person)
from sales
where shop_code in (1, 2, 4)
group by industry;

MDX - Filter from unrelated measure group

So is it possible to filter by one measure group and take the distinct members/people from that measure group and use it as a filter from another query from a different measure group.
Equivalent sql query
SELECT
sum(spend)
FROM
(SELECT distinct person_id FROM enrollment_fact WHERE program = 'blah') AS a
JOIN
(SELECT person_id, sum(spend) AS spend FROM sales_fact GROUP BY person_id) AS b
ON a.person_id = b.person_id
Assume I have two different measure groups in SSAS, one for spend and one from enrollment that are unrelated except for time and person_id
Also assume there are two many programs (thousands) to create columns/attributes for each person for each program to act as a member filter.
Is that the same as:
SELECT sum(spend) AS spend
FROM sales_fact
WHERE person_id IN
(
SELECT person_id
FROM enrollment_fact
WHERE program = 'blah'
GROUP BY person_id
)
If both these measure groups are in the same cube and the person_id dimension is shared then it looks possible in mdx.
The sub-query could be done with the NonEmpty function:
NONEMPTY(
[person].[person_id].[person_id].MEMBERS
, (
[program].[program].[blah]
, [measures].[someEnrollmentMeaure]
)
)
So adding this to an mdx WHERE clause will slice the cube by these person_ids:
SELECT
[measures].[someEnrollmentMeaure] ON 0
FROM [youCube]
WHERE
NONEMPTY(
[person].[person_id].[person_id].MEMBERS
,(
[program].[program].[blah]
,[measures].[someEnrollmentMeaure]
)
);

I can't get max and min from my table

How come this query returns an error?
select CUSTOMER, TOTAL_VALUE
from CUSTOMER, SALES
where TOTAL_VALUE in (select max(TOTAL_VALUE), min(TOTAL_VALUE)
from SALES)
When I just do max(TOTAL_VALUE) or min(TOTAL_VALUE) alone it works perfectly. But I need to get the min number in TOTAL_VALUE and max number in TOTAL_VALUE. Can anyone help me figure out why this query won't work for me? I would like to keep the structure that i have (using the in operator and nested subquery)
It returns an error because the subquery is returning two values, not one. Here is one fix:
select CUSTOMER, TOTAL_VALUE
from CUSTOMER cross join
SALES join
(select max(TOTAL_VALUE) as maxt, min(TOTAL_VALUE) as mint
from sales
) sm
where s.total_value in (sm.maxt, sm.mint);
That said, the query makes no sense. There you are going to get a list of every customer along with the value of the overall minimum and maximum sales.
This does answer your question. If you have another question, then provide sample data, desired results, in another question.
Try this (Joining SALES and CUSTOMER tables):
select C.CUSTOMER, MIN(TOTAL_VALUE), MAX(TOTAL_VALUE)
from SALES S
join CUSTOMER C on S.Customer_ID=C.Customer_ID
group by C.CUSTOMER
order by C.CUSTOMER

SQL database averaging a value for distinct people

I would like to average the weights which can be seen in the picture.
That means the calculation I want to make is : (50+65+70+68+70)/5
Do you know how to do that? (to specifically select the weights ones for every person using the household number and person number)
Average weights per person.....
Your initial question misleads into thinking you want the average for all.
SELECT HouseHoldNumber, PersonNumber, AVG(Weight) as AVG_Weight
FROM YOUR_TABLE
GROUP BY
HouseHoldNumber, PersonNumber
Simply add a WHERE if you want top do it for a specific house & Person.
Seem you want to average the distinct weights per household:
SELECT AVG(Weight)
FROM
(
SELECT DISTINCT HouseHoldNumber, Weight -- maybe need to add TravelNumber or PersonNumber
FROM tab
) AS dt
Use "Select AVG(your_column) From your_table"
uh
select avg(weight) from table
This will give you the average per household, per person.
SELECT [Household Number], [Person Number], AVG(Weight)
FROM Your_Table
GROUP BY [Household Number], [Person Number]

How can I rewrite this query without sub-queries?

So what I want to do:
I have a table that has some prices of some items of a store, what I want to do is to find the average price of all the items sold from that store, AND the sum of all similar items sold in store.
My columns are:
item_no
branch
totalamount
What is really important is that I have to avoid sub-queries so I couldn't do something like:
SELECT DISTINCT branch AS postcode, item_no, avg_price
FROM Prices
NATURAL JOIN (SELECT branch, AVG(totalamount) avg_price FROM Prices GROUP BY branch) av
WHERE sum > avg_price ORDER BY turnover DESC , branch;
Which does exactly what I want to do, nevertheless I have to do it without sub-queries.
edit 1 QUESTION:
IS THERE A DIFFERENCE between derived and temporary tables? so for the assignment , i am not allowed to use subqueries, OR temporary tables, so does my answer have any of those 2?
You can specify multiple aggregate statements on the same or different columns within the same SELECT statement. To see exactly what I mean have a look in books online.
http://msdn.microsoft.com/en-us/library/ms177677.aspx
here how you can do it,
SELECT branch AS postcode,
item_no,
AVG(totalamount) avg_price ,
SUM(totalamount) sum
FROM prices
WHERE SUM(totalamount) > avg_turnover
ORDER BY avg_turnover DESC ,
eatit_Order.branch
GROUP BY branch,
item_no;