Group by --> Not all results are shown - group-by

the following simple sql query does not show all results (one is missing):
SELECT SUM(stunden.stunden) as stunden, user.name, projekte.hmax as hmax
FROM stunden
LEFT JOIN user on stunden.user_id = user.ID
LEFT JOIN projekte ON stunden.projekt_id=projekte.ID
WHERE stunden.projekt_id=1031 GROUP BY user.ID
This one shows all:
SELECT stunden, user.name, projekte.hmax as hmax
FROM stunden
LEFT JOIN user on stunden.user_id = user.ID
LEFT JOIN projekte ON stunden.projekt_id=projekte.ID
WHERE stunden.projekt_id=1031
I can't figure out, whats wrong...!
Can u help me please ;-(
Best regards
Daniel
Edit:
The first query puts out all datasets correctly:
stunden username hmax
------------------------------
5 testuser_1 12
3 testuser_1 12
1 testuser_2 12
1 testuser_2 12
But i want an output like this:
stunden username hmax
------------------------------
8 testuser_1 12
2 testuser_2 12
Why does the second query not work but the first does?

Related

postgresql: joining 3 tables

*First post: apologies in advance if I left anything out. Please let me know and I'll update!
I’m looking for:
users who have not logged in over 30 days
where the user’s role does not equal ('owner', 'renter', 'manager')
and where the source does not equal 'internal'
I have 3 tables
last_login - has user login info (load_date, current_date, last_login)
user - has info about user being external vs internal (source)
role - which role user has (role_name)
I have to join 3 tables for my WHERE conditions. When I join the 3rd table , my results drop from 300 results to just 10 or so. I've checked the tables and I should get at least 200+ results.
Can anyone tell me what's wrong with my joins?
select u.id, u.username
from user as u
join last_login as ll
on u.username = ll.username
join role as r
on ll.username = r.username
where ll.loaddate = ll.current_date - 1
and ll.lastlogin < ll.current_date - 30
and u.source <> 'INTERNAL'
and r.role_name <> ('Owner', 'Renter', 'Manager')
Looking your query i suppose that you should use NOT IN instead of <>. Also try to use INNER or LEFT JOIN. Something like this for example:
select u.id, u.username
from user as u
left join last_login as ll
on u.username = ll.username
left join role as r
on ll.username = r.username
where ll.loaddate = ll.current_date - 1
and ll.lastlogin < ll.current_date - 30
and u.source NOT LIKE '%INTERNAL%'
and r.role_name NOT IN ('Owner', 'Renter', 'Manager')

Postgres SQL query pivot without crosstab

Select case_file_profile.case_file_id,
individual_profile.individual_name,
document_answer_details.document_template_question_id,
document.document_template_stage_id,
document.document_date,
individual_profile.individual_date_of_birth,
document.document_id,
document.document_template_id,
case_file_individuals.case_file_individual_relationship,
individual.individual_id,
case_file_date_3, case_file_close_date,
individual_profile.site_id,
document_answer_number.answer_number
FROM document
left join document_body on
(document.document_id = document_body.document_id)
left join document_answer_details on
(document_body.document_body_id = document_answer_details.document_body_id)
left join individual on
(document_body.entity_id = individual.entity_id)
left join individual_profile on
(individual.individual_id = individual_profile.individual_id)
left join case_file_individuals on
(individual_profile.individual_id = case_file_individuals.individual_id)
left join case_file_profile on
(case_file_individuals.case_file_id = case_file_profile.case_file_id)
full join document_answer_number on
(document_answer_details.document_answer_details_id =
document_answer_number.document_answer_details_id)
Where (conditions)
)
)
What it looks like
client id
Question ID
Answer num
53558
expected 100271
7
---------------------
------------------
------------
53558
completed 100272
6
---------------------
------------------
------------
What I'd like it to look like
client id
expected visits
completed visits
% of visits completed
53558
7
6
85%
---------------
----------------
--------------------
------------------------
The results are two rows of data per person. I need the results in separate columns with an additional column with a calculated value from the two numbers I need side by side. The numbers are connected to the particular person via case_file_id from the table case_file_individual. I'm not able to use crosstab because I don't have write permissions. I've also seen and tried CASE statements and haven't been able to get it to work.

How does one avoid Join placing a constraint on aggregate function?

[using postgres]
So the background to my scenario is:
I'm trying to get the average expenses by age where the user is active
cost = 40
Only 2 of the 33 year olds have purchased something
I have 34 active members that are 33 years old and active (whether or not they made a payment is irrelevant in this count)
with this in mind money spent per age = 40 / 34 = 1.18
what I am getting right now is = 40 / 2 = 20
I understand that it's constrained by the two users who made a purchase
So where did I get all of this?
select date_part('year', age(birthday)) as age,
avg(cost)
from person
inner join payment on person.person_id = payment.person_id
inner join product on payment.product_id = product.product_id
where
date_part('year', age(birthday))= 33 and user_state = 'active'
group by age
Unfortunately, when using an aggregate function (in this example avg())
it seems avg() is constrained to the result of the inner join (I've tried a left join to maintain having access to all users, it didn't seem to work since I still got the undesired result 20). Is there a way to avoid this? In other words can I make it so the avg() call is specific to my person table rather than the result of the join?
If it matters, this is how I am retrieving total sum.
select sum(cost)
from person
inner join payment on person.person_id = payment.person_id
inner join product on payment.product_id = product.product_id
where
date_part('year', age(birthday))= 33
and
user_state = 'active'
= 40
The obvious is to do the count of people I want and then do the sum seperately, but I'm trying to avoid going from one query to another.
avg will skip nulls so coalesce those null values into zeros and obviously left join:
select
date_part('year', age(birthday)) as age,
avg(coalesce(cost,0))
from
person
left join
payment on ...
left join
product on ...

Join Count and Sum Queries into Single Dataset

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

AdventureWorks SQL conflicting results issue

I'm working with the AdventureWorks example DB - we're running SQL Server 2008R2, so I assume that's the edition of AdventureWorks (I have read-only access). I'm trying to get a list of sales managers so that I can then determine a couple employee/manager relationships.
I'm getting two sets of three differently named people, with the same job title, with their CurrentFlag set to 1 (active) with slightly different queries. I do notice that one result group has the same contactID and employeeID, but I'm not sure what this may indicate.
So the question is: Why am I getting completely different results with these two queires? I would think I'd get six results for each - the queries are matching employee table Titles.
SQL Query 1:
select
c.FirstName,
c.LastName,
c.ContactID,
e.EmployeeID,
e.Title,
c.Title,
e.CurrentFlag
from Person.Contact c
inner join HumanResources.Employee e
on c.ContactID = e.ContactID
where
e.Title like '%Sales Manager%'
SQL Query 2:
SELECT
e.EmployeeID,
(c.FirstName + ' ' + c.LastName) as 'First Name and Last Name',
e.Title
FROM HumanResources.Employee e
INNER JOIN Person.Contact c
ON e.EmployeeID = c.ContactID
Where
e.Title LIKE '%Manager%'
AND
e.Title LIKE '%Sales%'
ORDER BY e.EmployeeID;
UPDATE: These are my results:
SQL Query 1:
------- ------- ---- --- ---------------------------- ---- --
Stephen Jiang 1011 268 North American Sales Manager NULL 1
Amy Alberts 1013 284 European Sales Manager NULL 1
Syed Abbas 1012 288 Pacific Sales Manager Mr. 1
SQL Query 2:
--- --- ----------- ---------------------------- --- --
268 268 Gary Drury North American Sales Manager Mr. 1
284 284 John Emory European Sales Manager Mr. 1
288 288 Julie Estes Pacific Sales Manager Ms. 1
The only diffrents i can see is this:
where
e.Title like '%Sales Manager%'
And this:
Where
e.Title LIKE '%Manager%'
AND
e.Title LIKE '%Sales%'
The first query says that bring me all titles that has '%Sales Manager%' you can have for ex this output:
Account Sales Manager
some Sales Manager
Sales Manager something else
The second question says bring me all the titles that has '%Manager%' and '%Sales%' so you can for ex have:
Sales Account Manager
some Sales some Manager some
Sales Manager some else thing
Manager Sales
And this join can not be corrent
INNER JOIN Person.Contact c
ON e.EmployeeID = c.ContactID
Don't you mean:
INNER JOIN Person.Contact c
ON e.ContactID= c.ContactID
The first query will match the rows where substring "Sales Manager" is present. But second one can match rows like "Managers of Sales Dep" as well. I mean the second doesn't care about positions of the words in the srting.
I believe that the results of first query is a subset of the results of second one.
UPDATE
You use different columns in JOIN clause, so it's normal that you got different results.