Using distinct on other field of selected ids postgresql - sql

I have this data
Table
id weight
1 1000
1 1000
2 2000
2 2000
3 3000
4 3000
I am trying to find average of weight of distinct ids except 4 and I need data in this format
id avg(weight)
1,2,3 2000
I have tried distinct but it gives me average including all duplicate values.
SELECT
String_agg(distinct id :: text, ', ') AS ids,
Round(Coalesce(Avg(weight), 0)) AS avg
FROM "table"
where id != 4
I have also tried group by id but it gives me data in different format and also it is not giving me correct average.
SELECT
String_agg(id :: text, ', ') AS ids,
Round(Coalesce(Avg(weight), 0)) AS avg
FROM "table"
where id != 4
group by id
so how can I find average for this?
Thanks.

You may try using your current logic on a subquery which finds the distinct records:
SELECT
STRING_AGG(id::text, ',' ORDER BY id) AS ids,
ROUND(COALESCE(AVG(weight), 0)) AS avg
FROM
(
SELECT DISTINCT id, weight
FROM "table"
WHERE id <> 4
) t;
Demo
Note: I added an ORDER BY clause to your STRING_AGG call, to ensure that the ids appear in the order you want.

Related

Using Derby SQL to calculate value for histogram

I have a table with various SKU in totes.
The table is totecontents with below columns:
ToteID
SKU
Each Tote can contain a maximum of 6 SKUs. (programmatically constrained)
select toteid, count(*) as qtypertote
from totecontents
group by toteid;
gives me a list of totes with the number of skus in each.
I now want to get to a table with following result
SkuCount Occurences where each row would have the ordinal value (1 through 6 ) and then the number of occurences of that value.
My efforts included the following approach
select count(*)
from
( select toteid, count(*) as qtypertote
from totecontents
group by toteid)
group by qtypertote;
Stung by the comments I performed more research. This works:
SELECT CountOfskus, COUNT(1) groupedCount
FROM
( SELECT COUNT(*) as countofskus, toteid
FROM totecontents
Group By toteid
) MyTable
GROUP BY countofskus;

SQL need to compare rows count values

I have a query that returns the ID, Name and count of the number of times an ID has been entered to the table.
SELECT
ID,
NAME,
COUNT(*) count
FROM
TABLE
GROUP BY
NAME, ID, CASE_DETAIL_ID
HAVING
COUNT(*) > 1;
This returns the following data:
ID
NAME
COUNT
123
HAT
10
123
UMBRELLA
10
123
TOWEL
10
123
WATER
8
555
HAT
3
555
UMBRELLA
10
555
TOWEL
10
555
WATER
10
322
UMBRELLA
5
322
TOWEL
20
322
WATER
20
I want to be able to query the row with a count of less than what the other rows with the same ID have. How can I do this? So that the end result is:
ID
NAME
COUNT
FULL COUNT
123
WATER
8
10
555
HAT
3
10
322
UMBRELLA
5
20
There are multiple IDs that we store and I only want the rows/names that have a count less than the rows with the same IDs have.
I have also tried -
WITH x AS
(SELECT ID, NAME, COUNT(*) count
FROM FRT.CASE_DETAIL_HISTORY
GROUP BY
NAME,
ID,
CASE_DETAIL_ID)
SELECT x.ID, t.NAME, X.COUNT, MIN(x.count)
FROM x
JOIN FRT.CASE_DETAIL_HISTORY t
on t.ID= x.ID
GROUP BY x.ID, t.ID, X.COUNT
However, this doesnt give me what I am looking for. I only want rows returned if the name's count doesnt match the 'mode' count of the ID.
I also have tried the below but keep facing errors:
WITH COUNT_OF_ROWS AS
(SELECT ID, NAME, COUNT(*) count
FROM TABLE
GROUP BY NAME, ID, CASE_DETAIL_ID
HAVING COUNT(*) >= 1),
MINIMUM AS
(SELECT COUNT_OF_ROWS.ID, COUNT_OF_ROWS.NAME,
MIN(COUNT_OF_ROWS.COUNT) MINI
FROM COUNT_OF_ROWS
JOIN TABLE CD on CD.ID = COUNT_OF_ROWS.ID
GROUP BY COUNT_OF_ROWS.ID, COUNT_OF_ROWS.NAME
)
select distinct COUNT_OF_ROWS.*, MINIMUM.MINI
from minimum, count_of_rows
where minimum.mini != count_of_rows.count;
Some sample data would help but you can use a CTE, and select the lowest using min() something like this:
WITH x AS(
SELECT t.id, t.nametext, COUNT(*) as count
FROM table t
GROUP BY id, t.nametext, CASE_DETAIL_ID
), y as(
SELECT x.id, MIN(x.[COUNT]) as mincount
FROM x
GROUP BY x.id
)
select y.id, x.nametext, y.mincount
from y
join x
on x.[COUNT] = y.mincount
and x.id = y.id
Or it can be done using top 1 and order by like this:
SELECT TOP 1 id, name, COUNT(*) as count
FROM TABLE
WHERE ID = 123
GROUP BY NAME, ID, CASE_DETAIL_ID
ORDER BY count DESC
But bare in mind that as this would select only the first row, this would only work with the where clause because it would always only return 1 row.
While if you use the CTE option it would work also if you want per id, without where id = 123.

Get Count Based on Combinations of Values from Second Column

I have a table format like below:
Id Code
1 A
1 B
2 A
3 A
3 C
4 A
4 B
I am trying to get count of code combinations like below:
Code Count
A,B 2 -- Row 1,2 and Row 6,7
A 1 -- Row 3
A,C 1 -- Row 4
I am unable to get the combination result. All I can do is group by but I am not getting count of IDs based in combinations.
You need to aggregate the rows, somehow, and do that twice. The code looks something like this:
select codes, count(*) as num_ids
from (select id, group_concat(code order by code) as codes
from t
group by id
) id
group by code;
group_concat() might be spelled listagg() or string_agg() depending on the database.
In SQL Server, use string_agg():
select codes, count(*) as num_ids
from (select id, string_agg(code, ',') within group (order by code) as codes
from t
group by id
) id
group by code;

What exactly does SELECT DISTINCT(COUNT(*)) do?

I used the following query and it returned what I wanted it to return, but I'm having a tough time wrapping my head around what the query is doing.
Query is nothing fancier than what's in the title: select distinct(count(*)) from table1
Distinct is not required in your SQL ,as you are going to get only result, count(*) without group by clause returns, count of all rows within that table.
Hence try this :
select count(*) from table1
Distinct is used for finding distinct values from a group of values:
say you have table1 , with column1 as :
Column1
----------
a
a
b
b
a
c
following sqls are run you will get output as :
1) select count(*) from table1
output :6
2) select distinct(count(*)) from table1
output :6
3) select count( distinct column1) from table1
output :3
Usually distinct is used inside count preferably with a particular column .
select count( distinct column_name_n ) from table1
The distinct is redundant... Select Count(*) with only one table can only generate one value, so distinct (which would eliminate duplicates) is irelelvant.
If you had multiple outputs, (if for example you were grouping on something) then it would cause the query to only display one output row for every distinct value of count(*) that would other wise be generated...
if, for example, you had
name
Bob
Bob
Bob
Bob
Mary
Mary
Mary
Mary
Dave
Dave
Al
George
then
select count(*)
From table
group By name
would result in
4
4
2
1
1
but
select distinct count(*)
From table
group By name
would result in
4
2
1

SQL Separating Distinct Values using single column

Does anyone happen to know a way of basically taking the 'Distinct' command but only using it on a single column. For lack of example, something similar to this:
Select (Distinct ID), Name, Term from Table
So it would get rid of row with duplicate ID's but still use the other column information. I would use distinct on the full query but the rows are all different due to certain columns data set. And I would need to output only the top most term between the two duplicates:
ID Name Term
1 Suzy A
1 Suzy B
2 John A
2 John B
3 Pete A
4 Carl A
5 Sally B
Any suggestions would be helpful.
select t.Id, t.Name, t.Term
from (select distinct ID from Table order by id, term) t
You can use row number for this
Select ID, Name, Term from(
Select ID, Name, Term, ROW_NUMBER ( )
OVER ( PARTITION BY ID order by Name) as rn from Table
Where rn = 1)
as tbl
Order by determines the order from which the first row will be picked.