I have records similar to the below
fruit day
apple 1/1/1990
apple 1/2/1990
apple 1/3/1990
plum 1/1/1990
orange 1/1/1990
orange 1/2/1990
orange 1/3/1990
I want to keep a running total for items for each day assuming item will increase by 1 every day. For example
fruit day count
apple 1/1/1990 1
apple 1/2/1990 2
apple 1/3/1990 3
plum 1/1/1990 1
orange 1/1/1990 1
orange 1/2/1990 2
You could use windowed COUNT:
SELECT *, COUNT(*) OVER(PARTITION BY fruit ORDER BY day)
FROM tab;
DBFiddle Demo
You can also use subquery:
select *,
(select count(*) from table where fruit = t.fruit and day <= t.day) count
from table t;
Related
I have this :
Person
Dinner
Paul
Apple
Alfred
Banana
John
Apple
Jimmy
Banana
Johnny
Strawberry
I want to give a specific number for each distinct value in the Dinner column in a select clause like this :
Person
Dinner
Group
Paul
Apple
1
Alfred
Banana
2
John
Apple
1
Jimmy
Banana
2
Johnny
Strawberry
3
I tried this get the groups :
SELECT case when (lag(Dinner) OVER (ORDER BY id) = Dinner) or (lead(Dinner) OVER (ORDER BY Dinner) = Dinner) then 1 else 0 end,* FROM restaurant ORDER BY Dinner desc)
And it gives me this :
Person
Dinner
Group
Paul
Apple
1
John
Apple
1
Alfred
Banana
0
Jimmy
Banana
0
Johnny
Strawberry
1
It only gives me 1 or 0 because of the case when case.
I'm pretty sure there's easier way to do it, but I didn't find any.
Any help ?
Why not use DENSE_RANK?
SELECT Person,
Dinner,
DENSE_RANK() OVER (ORDER BY Dinner ASC) AS [Group]
FROM (VALUES('Paul','Apple'),
('Alfred','Banana'),
('John','Apple'),
('Jimmy','Banana'),
('Johnny','Strawberry'))V(Person, Dinner);
I have a table:
table1
Type Attribute Value Count
Fruit Apple Sweet 1772
Fruit Apple Sour 1021
Fruit Apple Sweetest 930
Fruit Apple Sweetest 930
Fruit Orange Sweetest 200
Fruit Orange Sour 190
Fruit Orange Sweetest 160
Fruit Orange Sweetest 140
I need the first 3 rows based on type and attribute and count.
So, the output should be:
Type Attribute Value Count
Fruit Apple Sweet 1772
Fruit Apple Sour 1021
Fruit Apple Sweetest 930
Fruit Orange Sweetest 200
Fruit Orange Sour 190
Fruit Orange Sweetest 160
How can I grab the first 3 rows for each type, attribute, count?
The other answers by #GordonLinoff and #LukaszSzozda were based on the original post, and not on the clarification added later by the OP. The SQL Fiddle based on original post, using SQL in answer by #Gordon (which is basically identical to answer by #Lukasz as they posted the answers about the same time, before the clarification) returns 4 rows per Apple and 4 rows per Orange:
FOOD_TYPE ATTRIBUTE VALUE CNT SEQNUM
Fruit Apple Sour 1021 1
Fruit Apple Sweet 1772 1
Fruit Apple Sweetest 930 1
Fruit Apple Sweetest 930 2
Fruit Orange Sour 190 1
Fruit Orange Sweetest 200 1
Fruit Orange Sweetest 160 2
Fruit Orange Sweetest 140 3
Modified SQL here
select t.*
from (select Food.*,
row_number() over (partition by food_type, attribute order by cnt desc) as seqnum
from Food
) t
where seqnum <= 3;
returns the desired result:
FOOD_TYPE ATTRIBUTE VALUE CNT SEQNUM
Fruit Apple Sweet 1772 1
Fruit Apple Sour 1021 2
Fruit Apple Sweetest 930 3
Fruit Orange Sweetest 200 1
Fruit Orange Sour 190 2
Fruit Orange Sweetest 160 3
Use row_number():
select t.*
from (select t.*,
row_number() over (partition by type, attribute, value order by count desc) as seqnum
from t
) t
where seqnum <= 3;
You could use ROW_NUMBER:
WITH cte AS (
SELECT t.*, ROW_NUMBER(PARTIION BY "Type", Attribute ORDER BY "count" DESC) AS rn
FROM tab t
)
SELECT *
FROM cte
WHERE rn <= 3;
Here is my table. I am trying to get distinct person distinct fruit based on maximum number of fruits he has.
persons | fruits
David apple
David apple
David apple
David banana
David orange
Sam apple
Sam banana
Sam orange
Sam orange
Sam orange
Sam orange
Tom apple
Tom banana
Tom banana
Tom orange
I want to see my result as:
persons | fruits
David apple
Sam orange
Tom banana
I tried using count and max functions and group by, but was not able to get right result.
You can use distinct on:
select distinct on (person) person, fruit
from (select person, fruit, count(*) as cnt
from personfruits pf
group by person, fruit
) pf
order by person, cnt desc;
You can write this without the subquery as well:
select distinct on (person) person, fruit
from personfruits pf
group by person, fruit
order by person, count(*) desc;
However, that is a bit hard to follow for someone not really familiar with distinct on.
From what I understand, you want to see which fruit occurs most often, per person. If that's correct, this should work
SELECT persons, fruits
FROM (
SELECT
persons,
fruits,
RANK() OVER(PARTITION BY persons ORDER BY FruitCount DESC) AS FruitRank -- Rank fruit count per person
FROM (
SELECT
persons,
fruits,
count(*) FruitCount -- get # rows per (person, fruit) combination
FROM MyTable
GROUP BY persons, fruits
) src
) src
WHERE FruitRank = 1 -- Return fruit with largest FruitCount, per person
Say I have a table showing the type of fruit consumed by an individual over a 24 hour period that looks like this:
Name Fruit
Tim Apple
Tim Orange
Tim Orange
Tim Orange
Lisa Peach
Lisa Apple
Lisa Peach
Eric Plum
Eric Orange
Eric Plum
How would I get a table that shows only the most consumed fruit for each person, as well as the number of fruits consumed. In other words, a table that looks like this:
Name Fruit Number
Tim Orange 3
Lisa Peach 2
Eric Plum 2
I tried
SELECT Name, Fruit, Count(Fruit)
FROM table
GROUP BY Name
But that returns an error because Name needs to be in the GROUP BY statement as well. Every other method I've tried returns the counts for ALL values rather than just the maximum values. MAX(COUNT()) doesn't appear to be a valid statement, so I'm not sure what else to do.
This is a pain, but you can do it. Start with your query and then use join:
SELECT n.Name, n.Fruit
FROM (SELECT Name, Fruit, Count(Fruit) as cnt
FROM table as t
GROUP BY Name, Fruit
) as t INNER JOIN
(SELECT Name, max(cnt) as maxcnt
FROM (SELECT Name, Fruit, Count(Fruit) as cnt
FROM table
GROUP BY Name, Fruit
) as t
GROUP BY Name
) as n
ON t.name = n.name and t.cnt = n.maxcnt;
A table and I want to know the total of my rows over time. For example. Here's my table:
Date Fruit Sold
Mon apple 4
Mon pear 5
Mon orange 2
Tues apple 3
Tues pear 2
Tues orange 1
The table I want back is:
Fruit Sold
apple 7
pear 7
orange 3
What is a query that I can do this? However, with my real situation, I have hundreds of types of fruit. So how do I query with out specifying each type of fruit each time?
That would be along the lines of:
select fruit, sum(sold) as sold
from fruitsales
group by fruit
-- adding something like <<where date = 'Mon'>> if you want to limit it.
This will aggregate the individual sold columns (by summing) for each fruit type.
here is how to do it:
select fruit, sum(sold)
from table
group by fruit
cheers...
Group by Time
select fruit, sum(sold),substring(saletime,1,3) from table group by fruit,substring(saletime,1,3)