Partition by multiple columns having duplicate values in MS SQL - sql

As an example, I have two columns in a table
**Fruit Color**
Mango Yellow
Mango Yellow
Apple Red
Apple Red
Expected Output
**Rank Fruit Color**
1 Mango Yellow
1 Mango Yellow
2 Apple Red
2 Apple Red
Tried Row_number() but it doesn't seem to yield the expected output. Tried Rank() and Dense_Rank() as well but didn't get the expected outcome
SELECT ROW_NUMBER() OVER (PARTITION BY Fruit,Color order by Fruit) , Fruit,Color
from #temp
ORDER BY FRUIT
rwno Fruit Color
1 Apple Red
2 Apple Red
1 Mango Yellow
2 Mango Yellow

You want dense_rank() and no partition by:
SELECT DENSE_RANK() OVER (ORDER BY Fruit, Color), Fruit, Color
from #temp
ORDER BY FRUIT

Related

Get first N rows from table based on condition - Oracle SQL

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;

How do I select records from Sqlite table partially grouped?

I have a table like this. And I want to select Fruits grouped together based on the group_id but not the Vegetables and Nuts. For Vegetable and Nuts, I want them all.
group_id name type
-----------------------------------
1 Green Apple Fruit
1 Red Apple Fruit
1 Blue Apple Fruit
2 Green Peas Vegetable
2 Snow Peas Vegetable
2 Another Pea Vegetable
3 Ground Nut Nuts
3 Peanut Nuts
4 Carrot Vegetable
This is how I have tried right now. This works well, but I want to know if there is any simpler approach.
select * from Grocessaries GROUP BY group_id HAVING type in ('Fruit', 'Drinks')
UNION all
select * from Grocessaries where type in ('Vegetable', 'Nuts')
Basically, I want the result something like this (grouped Fruits and all Vegetables and Nuts)
group_id name type
-----------------------------------
1 Green Apple Fruit
2 Green Peas Vegetable
2 Snow Peas Vegetable
2 Another Pea Vegetable
3 Ground Nut Nuts
3 Peanut Nuts
4 Carrot Vegetable
Since you're handling Fruits (and Drinks) specially in the UI the actual name returned for them isn't that important so you could do
SELECT group_id,
CASE type
WHEN 'Fruits' THEN 'Fruits' -- or whatever you want to display
WHEN 'Drinks' THEN 'Drinks'
ELSE name
END NameGrouped,
type
FROM Grocessaries
GROUP BY group_id, NameGrouped, type

hive sql adding record count as column

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;

MSSQL - Select distinct products that are found in two columns

Suppose I have the following combinations in my dataset:
**ProductA** **ProductB**
Apple Banana
Apple Orange
Apple Pear
Banana Orange
Banana Pear
Orange Pear
How would I return a complete list of unique products in a single column? Desired output below:
**Products**
Apple
Banana
Orange
Pear
If I do select distinct, I obviously won't get the pear because it's not included in column ProductA.
Any help would be appreciated. Thanks!
You can UNION them together as a single column:
SELECT ProductA AS Products
FROM tablename
UNION
SELECT ProductB
FROM tablename;

Using a query to return the most frequent value and the count within a group using SQL in MS Access

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;