Could anyone suggest the query for the below scenario?
Table is as below
MachineName ManufacturedBy Amount
---------------------------------
A X 50
B X 50
C Q 30
D Q 30
The data should be as follows
MachineName ManufacturedBy Amount
----------------------------------
A X 50
B X 50
Subtotal 100
C Q 30
D Q 30
Subtotal 60
Grandtotal
Thanks
Sasi
You may use GROUP BY with ROLLUP:
SELECT
COALESCE(ManufacturedBy, 'All Manufacturers') AS ManufacturedBy,
COALESCE(MachineName, 'All Machines') AS MachineName,
SUM(Amount) AS Amount
FROM yourTable
GROUP BY ROLLUP (ManufacturedBy, MachineName);
Demo
I tried the below. It also worked for me.
SELECT
ManufacturedBy ,
MachineName ,
SUM AS Amount
FROM yourTable
GROUP BY GROUPING SETS (ManufacturedBy,(ManufacturedBy, MachineName),());
Thanks
Related
I want to be able to find out the monthly average of a count
My code at the moment is
SELECT
company,
COUNT(company) AS 'count'
FROM Information
GROUP BY company
I basically need it to be
SELECT company,
count(company) as 'count'
avg(count(company)) per month as 'average'
FROM Information
group by company
I want the result to look something like this
company count monthly average
a 5 6
b 13 14
c 2 2
d 45 45
e 23 21
f 6 5
A very simple approach would be to count per company and month first and then aggregate this data to get total and avarage per company.
select
company,
sum(cnt) as records,
avg(cnt) as records_per_month
from
(
select company, year(start_date), month(start_date), count(*) as cnt
from information
group by company, year(start_date), month(start_date)
) agg
group by company;
But read my comment to your question.
SELECT YEAR(yourDate) * 100 + MONTH(yourDate) YYMM,
company,
count(company) as 'count'
avg(count(company)) per month as 'average'
FROM Information
group by company
,YEAR(yourDate) * 100 + MONTH(yourDate)
I have one simple requirement. Below is my sql table.
ID Cname StartDate EndDate Value
1 x 01/15/2015 01/20/2015 50
2 x 01/17/2015 01/22/2015 60
3 y 02/15/2015 02/20/2015 40
4 y 02/17/2015 02/22/2015 80
I have date range and I want to convert this each date range into each day row. Along with that whenever there is a overlap of dates it adds the value.
Below is the sample output for more clarification.
Cname date value
x 1/15/2015 60
x 1/16/2015 60
x 1/17/2015 110
x 1/18/2015 110
x 1/19/2015 110
x 1/20/2015 110
x 1/21/2015 60
x 1/22/2015 60
y 2/15/2015 40
y 2/16/2015 40
y 2/17/2015 120
y 2/18/2015 120
y 2/19/2015 120
y 2/20/2015 120
y 2/21/2015 80
y 2/22/2015 80
Any help would be appreciated.
You can use the technique described here, in order to generate a date range for each interval of your table. Then simply group by Cname and date to get the desired result set:
;WITH natural AS
(
SELECT ROW_NUMBER() OVER (ORDER BY [object_id]) - 1 AS val
FROM sys.all_objects
)
SELECT m.Cname, d = DATEADD(DAY, natural.val, m.StartDate),
SUM(value) AS value
FROM mytable AS m
INNER JOIN natural ON natural.val <= DATEDIFF(DAY, m.StartDate, m.EndDate)
GROUP BY Cname, DATEADD(DAY, natural.val, m.StartDate)
ORDER BY Cname, d
The CTE is used to create a tally table. The numbers of this table are then used to add 1,2,3, ... days to StartDate until EndDate is reached.
If you group by Cname, [Date], then SUM will return the required value since it will add any overlapping records within each Cname partition.
SQL Fiddle Demo
I've got a table in SQL Server with several columns. The relevant ones are:
name
distance
create_date
I have many people identified by name, and every few days they travel a certain distance. For example:
name distance create_date
john 15 09/12/2014
john 20 09/22/2014
alex 10 08/15/2014
alex 12 09/05/2014
john 8 09/30/2014
alex 30 09/12/2014
What i would like is a query that for each person returns the sum of distance between two dates, and the create_date of the last entry during that date range, ordered by highest distance DESC. For example, given a date range of 08/01/2014 to 09/25/2014 I would expect this:
name distance create_date
alex 52 09/12/2014
john 35 09/22/2014
I thought of trying to do this with a SUM query with a sub query to get the newest date in the range but I think this is not efficient.
Does someone have an idea for this?
Thank you!
SELECT name,
SUM(distance) AS distance,
MAX(create_date) AS create_date
FROM Table
WHERE create_date >= '20140801' AND create_date < '20140925'
GROUP BY name
SQL Fiddle
You can use simple sum and max functions for this.
SELECT name,
SUM(distance) AS distance,
MAX(create_date) AS create_date
FROM theTable
WHERE create_date >= #startDate AND create_date < #endDate
GROUP BY name
ORDER BY distance DESC
I am new to sql, i had one doubt
select t1.PayeeCode,t1.PayeeName,t1.PayeeIFSCCode,t1.grossAmount as ga,t2.Deduction
as da,(t1.grossAmount-t2.Deduction) as SubAmount from (
(select PayeeCode,PayeeName,PayeeIFSCCode,PayeeBankAcNo,sum(PayeeAmount) as
grossAmount from tblPayees where AccountType='g' group by payeeCode, PayeeName,PayeeIFSCCode,PayeeBankAcNo) t1
inner join
(select PayeeCode,sum(PayeeAmount) as deduction from tblPayees where
AccountType='d' group by payeeCode) t2
on t1.PayeeCode=t2.PayeeCode
)
curent result
PayeeCode payeename payeeifsccode ga da subamount type
--------------------------------------------------------------
p1 x 123 1300 1400 100 g
p1 z 34 450 550 100 g
p1 y 35 150 150 0 d
p2 z 45 150 100 50 d
expected result:
PayeeCode payeename payeeifsccode ga da subamount type
--------------------------------------------------------------
p1 x 123 1750 1950 200 g
p1 y 35 300 250 50 d
Here this is the Column 'tblPayees.PayeeName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I know here why eeror is occured but , i dont want to group by payeeName, i wnat only payeecode.How to do that?
help me please
The problem is that you either need to include the column in group by clause or use an aggregate in select list like MIN, MAX, etc. otherwise the database engine doesn't know what to do with it i.e. what value from the group to select.
Now are you sure you cannot group on both columns? Can you have different PayeeName for the same PayeeCode? If not, you can include it in group by:
select PayeeCode, PayeeName from tblPayees group by PayeeCode, PayeeName
If PayeeName can vary for the same PayeeCode then you need to tell the database engine which value you want to select by means of aggregate function:
select PayeeCode, Max(PayeeName) as PayeeName from tblPayees group by PayeeCode
It is even possible to concatenate the PayeeName values in a comma-separated list, but this is out of scope of this question I guess.
I'm using SQL Server 2008, I want select random row record, and the total number of record is depend on another table's column value, how to do this?
My SQL statement is something like this, but wrong..
select top b.number a.name, a.link_id
from A a
left join B b on b.link_id = a.link_id
order by newid()
Here are my tables and the expected result.
Table A:
name link_id
james 100
albert 100
susan 100
simon 101
tom 101
fion 101
Table B:
link_id number
100 2
101 1
Expected result:
when run 1st time, result may be:
name link_id
james 100
susan 100
fion 101
2nd time result may be:
albert 100
susan 100
simon 101
3rd time could be:
james 100
albert 100
fion 101
Explaination
Refer to table B, link_id: 100, number: 2
meaning that Table A should select out 2 random record for link_id = 100
and need to select 1 random record for link_id=101
You can use the ROW_NUMBER() function:
SELECT A.name, A.link_id
FROM(
SELECT name,link_id, ROW_NUMBER()OVER(PARTITION BY link_id ORDER BY NEWID()) rn
FROM dbo.tblA
) AS A
JOIN dbo.tblB AS B
ON A.link_id = B.link_id
WHERE A.rn <= B.number;
Here is a SqlFiddle to show this in action: http://sqlfiddle.com/#!3/92eac/2
Try this:
SELECT a.*
FROM b
CROSS APPLY
(
SELECT TOP (b.number) a.*
FROM a
WHERE a.link_id = b.link_id
ORDER BY
NEWID()
) a
Also see: SQLFiddle