Average data in its own row - sql-server

I have data that returns the same value multiple times in one column, I only want to include the first value or even average the group, since they are all the same value. The group itself might have 3 rows of payments, but the payments are the same. I just want the three rows to show, but only the one payment in its own column.
In the data below I would like to add another column that averages Rich and Bob's value and inputs the amount in the top row for Rich and Bob.
Sample Data:
1 Rich 300
2 Rich 300
3 Rich 300
4 Bob 250
5 Bob 250

You probably want something like this:
Just paste this into an empty query window and exectue. Adapt to your needs...
DECLARE #tbl TABLE(ID INT, PersonName VARCHAR(100),Amount DECIMAL(6,2))
INSERT INTO #tbl VALUES
(1,'Rich',300)
,(2,'Rich',300)
,(3,'Rich',300)
,(4,'Bob',250)
,(5,'Bob',250);
WITH NumberedPerson AS
(
SELECT tbl.*
,ROW_NUMBER() OVER(PARTITION BY PersonName ORDER BY ID) PersonID
,AVG(Amount) OVER(PARTITION BY PersonName) PersonAvg
FROM #tbl AS tbl
)
SELECT *
,CASE WHEN PersonID=1 THEN PersonAvg ELSE NULL END AS AverageInFirstRow
FROM NumberedPerson
ORDER BY ID
But - to be honest - that is absolutely not the way how this should be done...

Related

Create 2 table ids, the second restarts when the first increments

I have the following table:
CREATE TABLE [dbo].[CASES]
(
[CASE_ID] INT NOT NULL,
[CASE_SECTION] INT NOT NULL,
[CASE_DATA] NVARCHAR(MAX) NOT NULL,
)
I want CASE_SECTION to increment based on whether the CASE_ID has changed.
Example:
CASE_ID CASE_SECTION CASE_DATA
---------------------------------------------
1 1 'FROG ATE THE FLY'
1 2 'FROG SAT ON LOG'
2 1 'CHEETAH CHEATAXED'
3 1 'BLUE CHEESE STINKS'
Basically, I want to do something similar to using ROW_NUMBER() OVER(PARTITION BY CASE_ID) as the CASE_DATA is inserted into the table.
Is there a way I can set the table up so that CASE_SECTION increments like this by default when data is inserted?
you can use rownumber:
Select row_number() over(partition by case_id order by case_data) as case_section, * from yourtable
If you can add either an IDENTITY or InsertedDateTime column to the table, you can use that to make Case_Section a computed column that uses row_number() partitioned by case_id.
Another poster suggested this, but if you order by case_data or any other column that isn't guaranteed to be ordinal, you run the risk that the value will move around as data is inserted and changes the order of the rows.
If your computation does row_number() over(partition by case_id order by [ColumnThatIncreasesWithEachInsert]) then the values will be stable over time.

How to use Loops in teradata

I have my table like this :
Id Name Country
1 Vaibhav India
2 Amit UK
3 Pranav US
I want to read all the records by counting the max number of records present using count(id) ,3 in this case and just increment the counter by 1 for each records processed .Simultaneously i wanted to print the result of my counter variable.
Can anyone suggest how to do it???
You already have the values 1,2,3?
You might want a ROW_NUMBER:
Select Name, Country,
ROW_NUMBER() OVER (ORDER BY Id) -- or whatever column you want
from tab

SSIS - Merging rows with aggregate determinations

I'm attempting to determine the best way, either in SSIS or straight TSQL, to merge two rows based on a given key, but taking specific data from each row based on various aggregate rules (MAX and SUM specifically). As an example, given the following dataset:
Customer Name Total Date Outstanding
12345 A 100 7/15/2015 500
12345 200 1/1/2015 300
456 B 500 1/2/2010 100
456 B 250 2/1/2015 900
78 C 100 9/15/2015 500
I wish to consolidate those to a single row per customer key, with the following rules as an example:
If any name is null, use a corresponding value for that customer that is not null
MAX(Total)
MAX(Date)
SUM(Outstanding)
The result set would be:
Customer Name Total Date Outstanding
12345 A 200 7/15/2015 800
456 B 500 2/1/2015 1000
78 C 100 9/15/2015 500
What's the best approach here? My first instinct is to query the table to join to itself on customer to get all values on a single row, and then use formulas in a Derived Column task in SSIS to determine the values to use. My concern there is that is not scalable - it works fine if I have a customer occur only twice in the main dataset, but the goal would be for the logic to work for N number of rows without needing to do a ton of rework. I'm sure there's also a TSQL approach that I'm missing here. Any help would be appreciated.
If name column in your query is not empty then you can do that simply by using aggregate function in one query
DECLARE #Customer TABLE
(
Customer INT, Name varchar(10), Total INT , PurchaseDate DATE , Outstanding INT
)
INSERT INTO #Customer
SELECT 12345,'A',100,'7/15/2015',500 UNION
SELECT 12345,'A',200,'1/1/2015',300 UNION
SELECT 456,'B',500,'1/2/2010',100 UNION
SELECT 456,'B',250,'2/1/2015',900 UNION
SELECT 78,'C',100,'9/15/2015',500
SELECT Customer,NAME ,MAX(Total), MAX(PurchaseDate), SUM(outstanding)
FROM #Customer
GROUP BY Customer, NAME
Demo
Now, if your name column is empty in few cases like you have mentioned in your example then you can update name table with correct name value

FInding max value from TOP selection grouped by key in SQL Server

Apologies for goofy title. I am not sure how to describe the problem.
I have a table in SQL Server with this structure;
ID varchar(15)
ProdDate datetime
Value double
For each ID there can be hundreds of rows, each with its own ProdDate. ID and ProdDate form the unique key for the table.
What I need to do is find the maximum Value for each ID based upon the first 12 samples, ordered by ProdDate ascending.
Said another way. For each ID I need to find the 12 earliest dates for that ID (the sampling for each ID will start at different dates) and then find the maximum Value for those 12 samples.
Any idea of how to do this without multiple queries and temporary tables?
You can use a common table expression and ROW_NUMBER to logically define the TOP 12 per Id then MAX ... GROUP BY on that.
;WITH T
AS (SELECT *,
ROW_NUMBER() OVER (PARTITION BY Id ORDER BY ProdDate) AS RN
FROM YourTable)
SELECT Id,
MAX(Value) AS Value
FROM T
WHERE RN <= 12
GROUP BY Id

How Can i Create a View or table out of two tables so that their rows are not merged?

I have two views that i want tho merge them into one view so that their records are not merge into one record! i mean suppose I have these tables :
Table one(suppose this is a sell table were our customer sold something!)
Date Description Fee Number Money
12/2/2012 something 10$ 20 200$
10/3/2012 somethingelse 20$ 30 600$
Table Two (suppose this is the table where our customer got money!)
Date Description Money
02/8/2012 someinfo 5000$
12/1/2012 stuff 3100$
And the resulting Table or view would be(based on the descending order on date) :
Date Description Fee Number Money
02/8/2012 someinfo 0 0 5000$
10/3/2012 somethingelse 20$ 30 600$
12/2/2012 something 10$ 20 200$
12/1/2012 stuff 0 0 3100$
How can I achieve this form? These two tables are separate ,but each has a unique personal ID which represents the salesmen account. ( so basically this means that these information belong to one person only.and our customer wants a report that gives him this specific view only!)
I tried using UNION on these two tables , but the rows where merged!!
If i use Joins there would only be a row where the two tables row are merged together .So I am stuck here and dont know what to do now .
I think you need UNION ALL not just UNION.
select Date, Description, Fee, Number, Money
from table1
UNION ALL
select Date, Description, 0 Fee, 0 Number, Money
from table2
order by Date
Try somthing like
CREATE VIEW vMyView
AS
SELECT [Date], [Description], [Fee], [Number], [Money]
FROM v1
UNION ALL
SELECT [Date], [Description], 0 AS [Fee], 0 AS [Number], [Money]
FROM v2
I think this should do it.
CREATE VIEW new_view AS
SELECT * FROM table_one
UNION ALL
SELECT *, 0 as Fee, 0 as Number FROM table_two;

Resources