Top nth of a report with rest as other - sql

I have a query that shows total amount by supplier. I want a report where the top 9 are shown and the rest is added together under an "other" supplier. Thus the detail shows top 9 suppliers, other groups the rest and the total on the report includes all.
I cant get the top 9 but how to I get the "other"
I use MS Access 2007
EDIT:
I also need to add a company name that is in another register. t_costed has the value, linked to t_register_2bre that has the company, linked to t_contacts_company that had the company name.
I know the amount of columns returned by the select query must be equal in the two unioned queries but I'm struggling with the INNER JOIN.

You could use a union query in the following way:
select top 9 t.amount
from table1 t
order by t.amount desc
union all
select sum(u.amount)
from table1 u
where
u.amount <
(
select min(v.amount)
from
(select top 9 w.amount from table1 w order by w.amount desc) v
)
Here, change all references to table1 with the name of your table.
EDIT:
With the additional information provided in your question, I would suggest the following (untested) SQL:
select top 9 c.company, t.amount
from
(t_costed t inner join t_register_2bre r on t.eventidbre = r.id_bre)
inner join t_contacts_company c on r.defaulting_partyid = c.id_contacts_company
order by t.amount desc
union all
select "Others" as company, sum(u.amount)
from t_costed u
where
u.amount <
(
select min(v.amount)
from
(select top 9 w.amount from t_costed w order by w.amount desc) v
)

Related

look up dynamic value from range in another table

I have 2 tables. The first one is a detail table with years and actual limit values. The second table has max control limits but only for certain years.
Table 1 & 2
What I want to do is list all of the detail records but pull in the values of the control limits if the year is less than the next one listed in the control table.
Desired results:
results
I have tried this query but it duplicates 2015, 2016 and 2017.
SELECT d.id, d.yeard, d.value, c.Column1
FROM detailTbl d
RIGHT OUTER JOIN controlTbl c ON d.dated <= c.datec
You may use Row_Number() function as the following to remove duplicates:
with cte as
(
Select D.id,D.yeard,D.val, C.limitVal,
row_number() over (partition by D.id order by C.yeard desc) as rn from
detailTbl D left join controlTbl C
on D.yeard>=C.yeard
)
Select B.id,B.yeard,B.val,B.limitVal from
cte B where B.rn=1 order by B.id
See a demo on MySQL 8.0 from here.

Sub query to count number of time an id appears in another table

Using SQL Server 2012. I have a table called deals that contains a primary key called deal_id along with 10 other fields. I also have a table called deals_country that contain a foreign key called deal_id.
It's possible that a record in deals contains numerous records in deals country. What I want to do is to count the number of times every deal_id from deals appears in deals_country?
Below is what I have tried without success.
select MA_DEALS.*, MA_DEALS_COUNTRY.mycount
from MA_DEALS cross apply
(
select count(MA_DEALS_COUNTRY.deal_id) as mycount
from MA_DEALS_COUNTRY
group by MA_DEALS_COUNTRY.deal_id
) MA_DEALS_COUNTRY
order by MA_DEALS.deal_id
Although you can use CROSS APPLY for this, I would start with the basic JOIN and GROUP BY query instead:
select MA_DEALS.*, dc.mycount
from MA_DEALS d left join
(select dc.deal_id, count(dc.deal_id) as mycount
from MA_DEALS_COUNTRY dc
group by dc.deal_id
) dc
on d.deal_id = dc.deal_id
order by d.deal_id;
Try this:
SELECT D.*,
DC.N
FROM MA_DEALS D
LEFT JOIN ( SELECT deal_id, COUNT(*) N
FROM MA_DEALS_COUNTRY
GROUP BY deal_id) DC
ON D.deal_id = DC.deal_id

Sum Distinct Rows Only In Sql Server

I have four tables,in which First has one to many relation with rest of three tables named as (Second,Third,Fourth) respectively.I want to sum only Distinct Rows returned by select query.Here is my query, which i try so far.
select count(distinct First.Order_id) as [No.Of Orders],sum( First.Amount) as [Amount] from First
inner join Second on First.Order_id=Second.Order_id
inner join Third on Third.Order_id=Second.Order_id
inner join Fourth on Fourth.Order_id=Third.Order_id
The outcome of this query is :
No.Of Orders Amount
7 69
But this Amount should be 49,because the sum of First column Amount is 49,but due to inner join and one to many relationship,it calculate sum of also duplicate rows.How to avoid this.Kindly guide me
I think the problem is cartesian products in the joins (for a given id). You can solve this using row_number():
select count(t1234.Order_id) as [No.Of Orders], sum(t1234.Amount) as [Amount]
from (select First.*,
row_number() over (partition by First.Order_id order by First.Order_id) as seqnum
from First inner join
Second
on First.Order_id=Second.Order_id inner join
Third
on Third.Order_id=Second.Order_id inner join
Fourth
on Fourth.Order_id=Third.Order_id
) t1234
where seqnum = 1;
By the way, you could also express this using conditions in the where clause, because you appear to be using the joins only for filtering:
select count(First.Order_id) as [No.Of Orders], sum(First.Amount) as [Amount]
from First
where exists (select 1 from second where First.Order_id=Second.Order_id) and
exists (select 1 from third where First.Order_id=third.Order_id) and
exists (select 1 from fourth where First.Order_id=fourth.Order_id);

Distinct on multi-columns in sql

I have this query in sql
select cartlines.id,cartlines.pageId,cartlines.quantity,cartlines.price
from orders
INNER JOIN
cartlines on(cartlines.orderId=orders.id)where userId=5
I want to get rows distinct by pageid ,so in the end I will not have rows with same pageid more then once(duplicate)
any Ideas
Thanks
Baaroz
Going by what you're expecting in the output and your comment that says "...if there rows in output that contain same pageid only one will be shown...," it sounds like you're trying to get the top record for each page ID. This can be achieved with ROW_NUMBER() and PARTITION BY:
SELECT *
FROM (
SELECT
ROW_NUMBER() OVER(PARTITION BY c.pageId ORDER BY c.pageID) rowNumber,
c.id,
c.pageId,
c.quantity,
c.price
FROM orders o
INNER JOIN cartlines c ON c.orderId = o.id
WHERE userId = 5
) a
WHERE a.rowNumber = 1
You can also use ROW_NUMBER() OVER(PARTITION BY ... along with TOP 1 WITH TIES, but it runs a little slower (despite being WAY cleaner):
SELECT TOP 1 WITH TIES c.id, c.pageId, c.quantity, c.price
FROM orders o
INNER JOIN cartlines c ON c.orderId = o.id
WHERE userId = 5
ORDER BY ROW_NUMBER() OVER(PARTITION BY c.pageId ORDER BY c.pageID)
If you wish to remove rows with all columns duplicated this is solved by simply adding a distinct in your query.
select distinct cartlines.id,cartlines.pageId,cartlines.quantity,cartlines.price
from orders
INNER JOIN
cartlines on(cartlines.orderId=orders.id)where userId=5
If however, this makes no difference, it means the other columns have different values, so the combinations of column values creates distinct (unique) rows.
As Michael Berkowski stated in comments:
DISTINCT - does operate over all columns in the SELECT list, so we
need to understand your special case better.
In the case that simply adding distinct does not cover you, you need to also remove the columns that are different from row to row, or use aggregate functions to get aggregate values per cartlines.
Example - total quantity per distinct pageId:
select distinct cartlines.id,cartlines.pageId, sum(cartlines.quantity)
from orders
INNER JOIN
cartlines on(cartlines.orderId=orders.id)where userId=5
If this is still not what you wish, you need to give us data and specify better what it is you want.

How to get the Sum from three tables? [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
How to get Sum from two tables?
I have three table first "products" second "items" third "sales"
The first and second tables have the same columns('code','quantity') but the third table has ('code','name') now I want sum quantity from first and second but want also want get name from third table which code is equal.
check my code
Select code, sum(qtd),name
from ( select a.code, a.qtd from product a
union all select b.code, b.qtd from items b
union all select c.name from sales c where b.code=c.code
)
group by code
first two giving me perfect values but third fiction giving error not showing also names.
Hum....
SELECT
sales.name,
(SELECT SUM(products.quantity) FROM products WHERE products.code = sales.code) as products.quantity,
(SELECT SUM(items.quantity) FROM items WHERE items.code = sales.code) as items_quantity,
FROM sales
When using UNION be sure that the columns you want to combine matches with each SELECT statement. The first two SELECT statement works fine because they have the same number of columns. The third one failed because it has only one column.
The following are basic rules for combining the result sets of two (or more) queries by using UNION:
The number and the order of the columns must be the same in all queries.
The data types must be compatible.
From your query, I think you want like this,
SELECT a.code, b.name, SUM(a.qtd) totalSUM
FROM product a
INNER JOIN sales b
ON a.code = b.code
GROUP BY a.code, b.name
UNION
SELECT a.code, b.name, SUM(a.qtd) totalSUM
FROM items a
INNER JOIN sales b
ON a.code = b.code
GROUP BY a.code, b.name
I think you want to do something like this, though it's not clear what the actual requirements are:
select code = t1.code ,
name = t2.name ,
qtd = t1.qtd
from ( select code = t.code ,
qtd = sum( t.qtd )
from ( select a.code, a.qtd from product a
union all select b.code, b.qtd from items b
) t
group by t.code
) t1
join sales t2 where t2.code = t1.code
Cheers!