Select items where their amount is greater than 5 - sql-server-2008-r2

I have no idea why it doesn't work... I need to select particular rows, where their amount is greater than 5.
SELECT member, COUNT(DISTINCT member) as membs
FROM myDB
WHERE membs>5
GROUP BY membe

Try this:
SELECT member, COUNT(member) as membs
FROM myDB
GROUP BY membe
HAVING COUNT(member) > 5

Related

Break array_agg column into batches

I have a query like the following:
SELECT mt.group_id, array_agg(mt.id) as my_array
FROM myTable mt
GROUP BY mt.group_id;
In some contexts the array contains too many elements and a max byte limit error is thrown.
Is there any way that I can break the array into separate smaller batches per row? So for example, if I wanted a maximum batch size of 2 the result set might look like:
group_id, my_array
1, {1,2}
1, {3,4}
2, {5}
You can use a window function to add a subgroup column, then group by that column in addition to the existing group_id.
Due to restrictions on where window functions can be used, this requires a nested select to add the subgroup at one level and group by it at a higher level.
with mytable as (select * from (values (1,1),(1,2),(1,3),(1,4),(2,5)) f(group_id,id))
SELECT group_id, array_agg(mt.id) as my_array from
(select *,(row_number() over (partition by group_id)-1)/2 as subgroup FROM myTable) mt
GROUP BY mt.group_id, subgroup order by group_id, subgroup;

Postgres distinct query in two columns

I want to write a postgres query. For every distinct combination of (career-id and uid) I should return the entire row which has max time.
This is the sample data
id time career_id uid content
1 100 10000 5 Abc
2 300 6 7 xyz
3 200 10000 5 wxv
4 150 6 7 hgr
Ans:
id time career_id uid content
2 300 6 7 xyz
3 200 10000 5 wxv
this can be done using distinct on () in Postgres
select distinct on (career_id, uid) *
from the_table
order by career_id, uid, "time" desc;
You can use CTE's for this. Something like this should work:
WITH cte_max_value AS (
SELECT
career_id,
uid,
max("time") as max_time
FROM mytable
GROUP BY career_id, uid
)
SELECT DISTINCT t.*
FROM mytable AS t
INNER JOIN cte_max_value AS cmv
ON t.uid = cmv.uid AND t.career_id = cmv.career_id AND t.time = cmv.max_time
The CTE gives you all the unique combinations of career_id and uid with the relevant maximum time, the inner join then joins the entire rows into this. I'm using if you get two rows with the same maximum time for the same combination of career_id and uid you will get two rows returned.
If you don't want that you will need to find a strategy to resolve this.
Edit: Also the proposed solution by a_hrose_with_name's solution is far nicer and unless you need some level of compatibility with other servers (sadly syntax varies) you should use that instead.

Counting Number of Users Whose Average is Greater than X in Postgres

I am trying to find out the number of users who have scored an average of 80 or higher. I am using Having in my query but it is not returning the count of number of rows.
The Schema looks like:
Results
user
test_no
question_no
score
My Query:
SELECT "user" FROM results WHERE (score >0) GROUP BY "user"
HAVING (sum(score) / count(distinct(test_no))) >= 80;
I get:
user
2
4
8
(3 rows)
Instead I would like to get 3 (number of rows) as the output. If I do count("user"), I get the count of number of tests for each user.
I understand this is related to use Group By but I need it for my Having clause. Any suggestions how I can do this is appreciated.
Update: Here is some sample data: http://pastebin.com/k1nH5Wzh (-1 means unanswered)
Thanks!
The query you found is good. Some minor simplifications:
SELECT count(*) AS ct
FROM (
SELECT 1
FROM result
WHERE score > 0
GROUP BY user_id
HAVING (sum(score) / count(DISTINCT test_no)) >= 80
) sub
DISTINCT does not require parentheses.
You can SELECT a constant value in the subquery. The value is irrelevant, since you are only going to count the rows. Slightly shorter and cheaper.
Don't use the reserved word user as column name. That's asking for trouble. I am using user_id instead.
I am not sure if this is an efficient way to do it but this seems to be working.
SELECT COUNT(*) FROM
(SELECT "user" FROM results WHERE (score >0) GROUP BY "user"
HAVING (sum(score) / count(distinct(test_no))) >= 80)) q1;

Get total count per ID change

how can I get a total count of sheets per change of sheet
example:
select sheetID,
..
from SomeTable
results look something like this:
sheetID
-----------
1000
1000
1000
1000
3000
3000
3000
so I want something like this:
select sheetID,
count(sheetID) as TotalsheetCount
from SomeTable
I just don't know how to break the count up per change of sheetID.
So I'd end up with this essentially:
sheetID TotalsheetCount
-------- -----------
1000 4
1000 4
1000 4
1000 4
3000 3
3000 3
3000 3
so 4 is because there are 4 1000s, 3 because there are 3 3000s. I am wanting to repeat the total count for that sheetID for each row, even though it's repeating, I want to provide that.
UPDATE, here's what I did per the replies but I'm getting way too many results now as compoared to the count where I did not add that partition count before
select MainTable.sheetID,
COUNT(SomeTable.sheetID)OVER(PARTITION BY SomeTable.sheetID) AS TotalSheetCount
table2.SomeField1,
table2.SomeField1
from MainTable
join (select distinct Sales.SalesKey from SomeLongTableName_Sales) sales on sales.SheetKey = MainTable.sheetKey
left outer join Site on MainTable.SiteKey = Site.SiteKey
join Calendar on sales.Date >= Calendar.StartDate
and sales.Date < Calendar.EndDate
group by SomeTable.sheetID
the joins and stuff is more realistic to my real query but formatted for this post to hide real field and table names.
You probably want to use a GROUP BY:
SELECT sheetID, COUNT(sheetID) AS TotalsheetCount
FROM dbo.SomeTable
GROUP BY sheetID
I am wanting to repeat the total count for that sheetID for each row,
even though it's repeating, I want to provide that
If you're using at least SQL-Server 2005, you can use a CTE with COUNT + OVER-clause, otherwise use a sub-query:
WITH CTE AS
(
SELECT sheetID,
COUNT(sheetID)OVER(PARTITION BY sheetID) AS TotalsheetCount
FROM SomeTable
)
SELECT sheetID, TotalsheetCount FROM CTE
Use the GROUP BY clause in a subquery to select the counts:
SELECT sheetID,
count(sheetID) as TotalsheetCount
FROM SomeTable
GROUP BY sheetID
This would make your whole query look like this:
SELECT t.sheetID,
counts.TotalsheetCount
FROM SomeTable t,
(SELECT sheetID, count(sheetID) as TotalsheetCount FROM SomeTable GROUP BY sheetID) counts
WHERE t.sheetID = counts.sheetID
It looks like you need a group-by expression:
select sheetID,
count(*) as TotalsheetCount
from SomeTable
group by sheetID
Is that it?
DC

Postgres: select the sum of values and then sum this again

I tried a lot but can´t find the right way.
If I select values in Postgres and sum them it looks like this:
SELECT name,sum(size) as total
FROM mytable group by name order by name;
How can I alter this so it also sum all values in total? I think I need a subselect but how?
Try this:
SELECT sum(a.total)
FROM (SELECT sum(size) as total
FROM mytable group by name) a
UPDATE
I'm sorry, I don't read that you want it all in the same query. For this reason the answer of greg it's better. However, other possibility if you have a postgresql version >= 9:
WITH mytableWith (name, sum) as
(SELECT name, sum(size)
FROM mytable
GROUP BY name)
SELECT 'grand total' AS name,
sum(sum) AS sum
FROM mytableWith
UNION ALL
SELECT name, sum
FROM mytableWith
I would use the ROLLUP function on POSTRGESQL:
SELECT name,sum(size) as total
FROM mytable
group by ROLLUP(name )
order by name;
This will give you a grand total of any value that you aggregate and can also be used for aggregating multiple columns.
Hope it helps!
If you want all results with the same SELECT, you could do something like
SELECT
'grand total' AS name,
sum(size) AS sum
FROM
mytable
UNION ALL
SELECT
name,
sum(size) AS sum
FROM
mytable
GROUP BY
name;
Hope it helps…
Well this should help you:
select sum(innerselect.innertotal) as outertotal from
(select sum(size) as innertotal from mytable group by name) as innerselect