Summing Values From Calculated Column From Distinct Rows - sql

I have data in the following format.
Column 1 and Value from the database. I use a LEFT() function to extract Column 2. Where I need help is to sum the values from the newly calculated Column 2 and list the sums a new column.
Any help is appreciated. Thanks.

Basically, you seem to want an aggregation with a function for the aggregation key:
select left(column1, 1), sum(value)
from t
group by left(column1, 1);

SELECT *
,CalculatedColumn2 = LEFT(Column1,1)
,Value
,CalculatedSum = SUM(Value) OVER (PARTITION BY LEFT(Column1,1))
FROM
Table
While Gordon's answer get's you the SUM if you want it per row you can use a partitioned window Function such as SUM() OVER.

You can achieve it using Windows Functions
Try the following query
SELECT column1
, SUBSTRING(column1,1,1) as [calculated column 2]
,value
, SUM(value) OVER(PARTITION BY SUBSTRING(column1,1,1) )
FROM table1
And you can also use LEFT(Column1,1) instead of SUBSTRING(column1,1,1) (String Functions)

Get the first character from column1 using LEFT function and use that result set as a sub-query and find the sum of value column group by the new column.
Query
SELECT t.[column2], SUM(t.[value]) as [value] FROM(
SELECT [column1], LEFT([column1], 1) AS [column2], [value]
FROM [your_table_name]
)t
GROUP BY t.[column2];

Add computed persisted column which can contain values from left(column1, 1). You shloudn't repeat your code.
alter table tbl add newcomputedcol column (left(column1, 1)) persisted
Use grouped subqry or use over clause:
select
*,
sum(value) over() over(partition by newcomputedcol) SumPerNewComputedCol
from tbl
Your new persisted column can be indexed, your qry can be added into view.

Related

How to explicitly access a new column in SQL from GROUP BY?

I'm using SQLite.
I reduced my problem to this query:
WITH list_5([value]) AS (VALUES(1),(2),(3))
SELECT (t1.[value] * 2) AS [value], SUM(t1.[value]) AS [sum]
FROM [list_5] t1
GROUP BY value / 2;
I want SQL to group by the new value column, instead of the old one.
I can explicitly refer to the old value (t1.value), but how do I refer to the new one?
No matter what I do, group by uses the old value of value, instead of the column that's multiplied by 2.
The obvious solution would be to change the column names to unique names. But that's exactly what I'm trying to avoid.
Is there a way to do this?
You could use positional notation:
SELECT (t1.[value] * 2) AS [value], SUM([t1.value]) AS [sum]
FROM [list_5] t1
GROUP BY 1;
Or give it a name that does not conflict with a table column:
SELECT (t1.[value] * 2) AS computed, SUM([t1.value]) AS [sum]
FROM [list_5] t1
GROUP BY computed;
Please use the same sql operation in the Group by clause instead of alias,
WITH list_5([value]) AS (VALUES(1),(2),(3))
SELECT (t1.[value] * 2) AS [value], SUM([t1.value]) AS [sum]
FROM [list_5] t1
GROUP BY (t1.[value] * 2);

Add ID column to a query result

This is my first time asking a question about T-SQL and I am a beginner with it. I have a SQL query which consists of two CTE's filtered down to less than 10 rows. I am using a SUM statement to get a running total:
Sum(Diff) OVER(ORDER BY DateAdded) AS Summary
DateAdded has the same value for several rows. Therefore, it does not give me a running total for each row. I need to create a field that simply counts the number of rows (similar to a PK in a DB table) so I can use it for my ORDER BY clause. If my understanding is correct, this is what I need to do to make it work. How can I add an enumerated column to the query result set? Please note, I do not want to ALTER a table, just add a column to the query result. I hope what I wrote is clear. Thank you!
Instead of using count() or sum() you can use row_number() which will give a distinct row number, starting at 1, for each row in your result set:
SELECT ROW_NUMBER() OVER (ORDER BY dateAdded) as Summary
Try this:
DECLARE #Result TABLE
(
DT DATETIME
)
INSERT INTO #Result SELECT '1 Jan 1900'
INSERT INTO #Result SELECT '1 Jan 1900'
SELECT ROW_NUMBER() OVER(ORDER BY DT DESC) AS "Row Number", DT
FROM #Result
I believe that you can just add NEWID() to your ORDER BY:
SELECT SUM(diff) OVER (ORDER BY DateAdded, NEWID()) AS Summary

Select all columns for a distinct column

I need to fetch distinct rows for a particular column from a table having over 200 columns. How can I achieve this?
I used
Select distinct col1 , * from table;
but it failed.
Please suggest an elegant way to achieve this.
Regards,
Tarun
The solution if you want one row for each distinct value in a particular column is:
SELECT col1, MAX(col2), MAX(col3), MAX(col4), ...
FROM mytable
GROUP BY col1
I chose MAX() arbitrarily. It could also be MIN() or some other aggregate function. The point is if you use GROUP BY to make sure to get one row per value in col1, then all the other columns must be inside aggregate functions.
There is no way to write MAX(*) to get that treatment for all columns. Sorry, you will have to write out all the column names (at least those that you need in this query, which might not be all 200).
We can generate a sequence of ROW_NUMBER() for every COL1 and then select the first entry of every sequence.
SELECT * FROM
(
SELECT E.* , ROW_NUMBER() OVER( PARTITION BY COL1 ORDER BY 1) AS ID
FROM YOURTABLE E
) MYDATA
WHERE MYDATA.ID = 1
A working example in fiddle

How to retrieve specific rows from SQL Server table?

I was wondering is there a way to retrieve, for example, 2nd and 5th row from SQL table that contains 100 rows?
I saw some solutions with WHERE clause but they all assume that the column on which WHERE clause is applied is linear, starting at 1.
Is there other way to query a SQL Server table for a specific rows in case table doesn't have a column whose values start at 1?
P.S. - I know for a solution with temporary tables, where you copy your select statement output and add a linear column to the table. I am using T-SQL
Try this,
SELECT * FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY ColumnName ASC) AS rownumber
FROM TableName
) as temptablename
WHERE rownumber IN (2,5)
With SQL Server:
; WITH Base AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY id) RN FROM YourTable
)
SELECT *
FROM Base WHERE RN IN (2, 5)
The id that you'll have to replace with your primary key or your ordering, YourTable that is your table.
It's a CTE (Common Table Expression) so it isn't a temporary table. It's something that will be expanded together with your query.
There is no 2nd or 5th row in the table.
There is only the 2nd or 5th result in a resultset that you return, as determined by the order you specify in that query.
If you are on SQL Server 2005 or above, you could use Row_Number() function. Ex:
;With CTE as (
select col1, ..., row_number() over (order by yourOrderingCol) rn
from yourTable
)
select col1,...
from cte
where rn in (2,5)
Please note that yourOrderingCol will decide the value of row number (i.e. rn).

MSSQL Select statement with incremental integer column... not from a table

I need, if possible, a t-sql query that, returning the values from an arbitrary table, also returns a incremental integer column with value = 1 for the first row, 2 for the second, and so on.
This column does not actually resides in any table, and must be strictly incremental, because the ORDER BY clause could sort the rows of the table and I want the incremental row in perfect shape always.
The solution must run on SQL Server 2000
For SQL 2005 and up
SELECT ROW_NUMBER() OVER( ORDER BY SomeColumn ) AS 'rownumber',*
FROM YourTable
for 2000 you need to do something like this
SELECT IDENTITY(INT, 1,1) AS Rank ,VALUE
INTO #Ranks FROM YourTable WHERE 1=0
INSERT INTO #Ranks
SELECT SomeColumn FROM YourTable
ORDER BY SomeColumn
SELECT * FROM #Ranks
Order By Ranks
see also here Row Number
You can start with a custom number and increment from there, for example you want to add a cheque number for each payment you can do:
select #StartChequeNumber = 3446;
SELECT
((ROW_NUMBER() OVER(ORDER BY AnyColumn)) + #StartChequeNumber ) AS 'ChequeNumber'
,* FROM YourTable
will give the correct cheque number for each row.
Try ROW_NUMBER()
http://msdn.microsoft.com/en-us/library/ms186734.aspx
Example:
SELECT
col1,
col2,
ROW_NUMBER() OVER (ORDER BY col1) AS rownum
FROM tbl
It is ugly and performs badly, but technically this works on any table with at least one unique field AND works in SQL 2000.
SELECT (SELECT COUNT(*) FROM myTable T1 WHERE T1.UniqueField<=T2.UniqueField) as RowNum, T2.OtherField
FROM myTable T2
ORDER By T2.UniqueField
Note: If you use this approach and add a WHERE clause to the outer SELECT, you have to added it to the inner SELECT also if you want the numbers to be continuous.