SQL - show groups plus subgroups - sql

I have a StockLines table. See image below. How can I extract groups and group items at once from the server. The structure I want to extract from code is:
Site,
Article,
List of StockLines
I do:
select top 20 Site, Article, SUM(Quantity)
from StockLines
group by Site, Article
that gives me the groups. Now foreach group I want to return 10 sub items. Should I create a new select foreach group to get its child items?

This will return rows with least 10 ids (change it as needed) for every group of Site, Article along with the sum of all the rows in the group.
select *
from(
select *, sum(Quantity) over(partition by Site, Article) s
-- change order by expression as needed
, row_number() over(partition by Site, Article order by Id) rn
from StockLines
) t
where rn <= 10;

Related

I need first 2 occurrences of duplicate id in the output(image attached) using sql

want first 2 occurrence of duplicate ID'S in the output, desired output in image attached.
Please help
I'm not sure what you meant by "1st occurrence" because sql select queries are unorder unless you specified the order. So I'm assuming you are using alphabetical ordering on the emails.
SELECT t.id, t.email, t.state_code FROM (
SELECT id, email, state_code,
ROW_NUMBER() OVER(partition by id ORDER BY email desc) as cnt
FROM testdb
group by id, email, state_code
) as t
WHERE t.cnt <= 2
db fiddle link

Snowflake SQL code to show only second record for items with duplicate ID

I'm trying to get my head around SQL and am using Snowflake as a testbed to do this. I have a table with products which have multiple reviews against them. I am trying to structure a query to only show products with 2 or more reviews and then only show the second review. As I say, this is merely me trying to better understand SQL so selecting the second review is a random ask. The table is made up of 4 columns. 1 is Product ID, 2 is Product Name, 3 is Review and 4 is Date Review was posted.
Thanks in advance for any help.
You use row_number() for this type of query:
select t.*
from (select t.*,
row_number() over (partition by product_id order by date_review asc) as seqnum
from t
) t
where seqnum = 2;
You can use a windowing function like ROW_NUMBER() to make numbered groupings, eg:
WITH Review_Sequence (
SELECT r.*,
ROW_NUMBER() OVER (PARTITION BY Product_ID ORDER BY Review_Date) Review_No
FROM Reviews r
)
SELECT * FROM Review_Sequence WHERE Review_No = 2

SQL Getting Top 2 Results for each individual column value

I have a table 'Cashup_Till' that records all data on what a particular till has recorded in a venue for a given day, each venue has multiple tills all with a designated number 'Till_No'. I need to get the previous 2 days entries for each till number. For each till Individually I can do this...
SELECT TOP 2 T.* FROM CashUp_Till T
WHERE T.Till_No = (Enter Till Number Here)
ORDER BY T.Till_Id DESC
Some venues have 20-30 tills so Ideally I need to do all the tills in one call. I can pass in a user defined table type of till numbers, then select them in a subquery, but that's as far as my SQL knowledge takes me, does anyone have a solution?
Here is one way:
SELECT T.*
FROM (SELECT T.*,
ROW_NUMBER() OVER (PARTITION BY Till_No ORDER BY Till_Id DESC) as seqnum
FROM CashUp_Till T
) T
WHERE seqnum <= 2;
This assumes that there is one record per day, which I believe is suggested by the question.
If you have a separate table of tills, then:
select ct.*
from t cross apply
(select top 2 ct.*
from cashup_till ct
where ct.till_no = t.till_no
order by till_id desc
) ct;

Calculating Top Ten Categories in SSIS

I'm using an SSIS package to update my contents daily basis. There are thousands of contents which have different Moderation ID's and I want to calculate top ten categories FOR EACH Moderation ID. Before I realized that I should calculate it for each ModerationId, I used this query to get the Contents to be updated:
SELECT TOP 10 ModerationId, Category, COUNT(ContentSeqNum) AS Total FROM Content
WHERE Category IS NOT NULL
GROUP BY ModerationId, Category ORDER BY ModerationId, Total DESC
And that was a faulty approach because this query calculates top ten Categories for all the data, which should be different top ten categories for different ModerationId's.
How can I change this query to calculate Top 10 Categories for each ModerationId?
Use Window Function to get the to calculate top ten categories for Moderation ID. Try this.
SELECT moderationid,
category,
total
FROM (SELECT Row_number() OVER (partition BY moderationid
ORDER BY Count(contentseqnum)) Rn,
moderationid,
category,
Count(contentseqnum) AS Total
FROM content
WHERE category IS NOT NULL
GROUP BY moderationid,
category) A
WHERE rn <= 10
Use Row_number() function
select * from
(
select *,
row_number() over(partition by ModerationId order by ModerationId) as sno
from Content WHERE Category IS NOT NULL
) as t
where sno<=10
Find more methods at http://beyondrelational.com/modules/2/blogs/70/posts/10845/return-top-n-rows.aspx
Try this:
SELECT TOP(10) ModerationId, Category, COUNT(ContentSeqNum) OVER(PARTITION BY ModerationId ORDER BY ModerationId) AS Total
FROM Content
WHERE Category IS NOT NULL
ORDER BY Total DESC

I need the Top 10 results from table

I need to get the Top 10 results for each Region, Market and Name along with those with highest counts (Gaps). There are 4 Regions with 1 to N Markets. I can get the Top 10 but cannot figure out how to do this without using a Union for every Market. Any ideas on how do this?
SELECT DISTINCT TOP 10
Region, Market, Name, Gaps
FROM
TableName
ORDER BY
Region, Market, Gaps DESC
One approach would be to use a CTE (Common Table Expression) if you're on SQL Server 2005 and newer (you aren't specific enough in that regard).
With this CTE, you can partition your data by some criteria - i.e. your Region, Market, Name - and have SQL Server number all your rows starting at 1 for each of those "partitions", ordered by some criteria.
So try something like this:
;WITH RegionsMarkets AS
(
SELECT
Region, Market, Name, Gaps,
RN = ROW_NUMBER() OVER(PARTITION BY Region, Market, Name ORDER BY Gaps DESC)
FROM
dbo.TableName
)
SELECT
Region, Market, Name, Gaps
FROM
RegionsMarkets
WHERE
RN <= 10
Here, I am selecting only the "first" entry for each "partition" (i.e. for each Region, Market, Name tuple) - ordered by Gaps in a descending fashion.
With this, you get the top 10 rows for each (Region, Market, Name) tuple - does that approach what you're looking for??
I think you want row_number():
select t.*
from (select t.*,
row_number() over (partition by region, market order by gaps desc) as seqnum
from tablename t
) t
where seqnum <= 10;
I am not sure if you want name in the partition by clause. If you have more than one name within a market, that may be what you are looking for. (Hint: Sample data and desired results can really help clarify a question.)