Suming up Rows Based On Repetition Of Another Column - sql

I Don't Know Why My Previous Topic Was Marked!!!???
This Is What I've Done So Far. I Can't Think Of Anything Else.
So Many Things I've Done To Reach To This Point Which Is Illustrated In My Problem Section. Which For Simplification I Made Name A,B,C,... .I'm Not Giving You My Homework.
My Problem:

Here is a SQL for SqlServer 2008 to solve your problem.
with data as (select name, count(*) as occurrence, sum(value) as sumvalue from mytab group by name)
select * from data where
occurrence=(select max(occurrence) from data)
and sumvalue=(select max(sumvalue) from data data2 where data2.occurrence=data.occurrence)
In data the needed values are collected (sum and count). Now we select the rows with max occurrence and filtering out the rows with the max value.
http://sqlfiddle.com/#!3/56b00/4

SELECT [Name], [Value]
FROM (
SELECT *, RANK() OVER(ORDER BY [Count] DESC, Value DESC) [rn]
FROM (
SELECT [Name], SUM(Value) [Value], COUNT(1) [Count]
FROM MyTable
GROUP BY Name
) t
) t
WHERE rn = 1
SQL Fiddle
or more simply
SELECT TOP 1 WITH TIES [Name], [Value]
FROM (
SELECT [Name], SUM(Value) [Value], COUNT(1) [Count]
FROM MyTable
GROUP BY Name
) t
ORDER BY [Count] DESC, Value DESC
SQL Fiddle

Related

Perform pivot operation on the table but facing problem as it requires multiple aggregate function to segregate dates into two columns

I have this table named hotel which contains EmpId and their corresponding [check-in/out] column in datetime format.
Now, I want the data in table to look like this.
I have tried following simple query and it's working correctly:
select EmpId, min([Check-in/out]) as Checkin, max([Check-in/out]) as Checkout
from [dbo].[hotel]
group by EmpId;
But i want to do it using pivot operator in sql server. I have tried the following query but it's incorrect:
select EmpId, Min([Check-in/out]) AS Checkin, Max([Check-in/out]) AS Checkout
FROM
(select EmpId, [Check-in/out] from [dbo].[hotel]) AS SourceTable
PIVOT
(
min([Check-in/out])
FOR [Check-in/out] IN(Checkin)
)AS PivotTable1
PIVOT
(
max([Check-in/out])
FOR [Check-in/out] IN(Checkout)
)AS PivotTable2;
Here again my comment as answer with an example:
I suggest using cte / subqueries in order to approach this problem... first of all, select EmpID, time and rownumber (partition by empid and order by time) - this gives you all checkins with odd rownumber and all checkouts with even rownumber. Next - basing on this query - select empid, time and CASE WHEN rownumber%2=0 THEN 'CHECKOUT' ELSE 'CHECKIN' END AS CheckInOut... this result again can be used in your pivot statement
Example:
WITH cte AS(
SELECT *, ROW_NUMBER() OVER (PARTITION BY EmpID ORDER BY CheckInOut) rn
FROM T1
),
cteInOut AS(
SELECT EmpID, CheckInOut, CASE WHEN rn%2 = 0 THEN N'CheckOut' ELSE N'CheckIn' END AS CheckInOutState
FROM cte
),
cteInOuntSrt AS(
SELECT EmpID, CheckInOut, CheckInOutState, ROW_NUMBER() OVER (PARTITION BY EmpID, CheckInOutState ORDER BY CheckInOut) rn1
FROM cteInOut
)
select EmpID, rn1 AS CheckIndIdx, CheckIn, CheckOut
from cteInOuntSrt
pivot
(
min(CheckInOut)
for CheckInOutState in ([CheckIn], [CheckOut])
) piv
ORDER BY 1, 2;
fiddle: http://sqlfiddle.com/#!18/af6f3/1/1
If the values line up, you can use lead() and row_number():
select c.empid, checkin, checkout
from (select c.*, [Check-in/out] as checkin,
lead([Check-in/out]) over (partition by empid order by [Check-in/out]) as checkout,
row_number() over (partition by empid order by [Check-in/out]) as seqnum
from [Check-in/out] c
) c
where seqnum % 2 = 1;
This does the following calculations:
Calculate the next date/time value.
Enumerate the rows, starting the count from 1.
Taking the odd-numbered rows. These are the check ins.

How to get the max row number in the Partition over by SQL Syntax?

We have duplicate file name record in the file name column on various dates. I need to pick the Max - Rownumber of filename and its corresponding date.
with cte as
(
select [FileName], ProcessDate,
ROW_NUMBER() over (partition by [FileName] order by [FileName]) RowNumber
from StagingTable
)
select * from cte
order by rownumber desc
This is not addressing your question but I think this is what you want. This will give you the last ProcessDate with one SELECT:
SELECT
[FileName]
,MAX (ProcessDate) AS LastProcessDate
,COUNT (*) FileNameOccurence
FROM StagingTable
GROUP BY [FileName]
If so, don't make it more complicated with nested queries.
with cte as
(
select [FileName], ProcessDate,
ROW_NUMBER() over (partition by [FileName] order by [FileName] desc) RowNumber
from StagingTable
)
select * from cte
where RowNumber = 1
Assuming you actually want the latest file where there are more than one with the same file name - You don't necessarily need a CTE - a subquery would work just fine
select *
from(
select [FileName], ProcessDate, ROW_NUMBER() over (partition by [FileName] order by
ProcessDate desc) RN
from StagingTable
)files
where RN = 1

SQL remove duplicate row

I have next query
select No,
Item,
Quantity,
Status
from myTable
when execute query I get
I want to distinct No but with last import quantity, something like this:
Only to get last data from this table group by No
WITH CTE (No, DuplicateCount)
AS
(
SELECT No,
ROW_NUMBER() OVER(PARTITION BY No
ORDER BY No) AS DuplicateCount
FROM myTable
)
Delete from CTE WHERE DuplicateCount >1
If I understood correctly the question
Try this
SELECT * FROM myTable GROUP BY No
If you are using MS SQL Server
Try this
;WITH CTE AS
(
select ROW_NUMBER() over (partition by [No] order by [No] desc) as rn,*
from myTable
)
select No,
Item,
Quantity,
Status
from CTE where rn=1;

Select Top 100 Groups

I have thousands of groups in a table, something like :
1..
1..
2..
2..
2..
2..
3..
3..
.
.
.
10000..
10000..
How can i make a select that give me the Top 3 groups each time.
I Want something like select Top 3 from rows , but it have to return the first three groups not the first three rows.
You can try this :
;with cte as (
select distinct groupId from mytable order by groupid
)
select * from mytable where TheGroupId in (select top 3 groupdid from cte)
You can use DENSE_RANK to assign a number to each group. All members of the same group will have the same number. Then in an outer query, select top 3 groups:
SELECT *
FROM (SELECT *, DENSE_RANK() OVER (ORDER BY id) AS rnk
FROM mytable ) t
WHERE t.rnk <= 3
The above query assumes that id is the column used to group records together.
SQL Fiddle Demo
Use Ranking function Row_Number() :
SELECT *
FROM (SELECT *,
Row_number()
OVER(
partition BY GroupId
ORDER BY GroupId) AS [rn]
FROM YourTable) t
WHERE rn <= 3
Check this MSDN doc for details of all ranking functions.
There is a sql TOP statement that does this
SELECT TOP number|percent column_name(s) FROM table_name;
a description of what it does and how it is used in alternative sql statements for example for mysql and ms access can be found here: http://www.w3schools.com/sql/sql_top.asp
My bad i misread your question, this will return the top rows not groups, could you explain what you are trying to do in more detail?
SELECT *
FROM
(SELECT *
,ROW_NUMBER() OVER (PARTITION BY [Group] ORDER BY [Group] ASC)rn
FROM TableName
)A
WHERE rn <= 3

Combine Row Values to "Others"

I have a maybe really tricky question. I have a table with costs, very simple:
Cost name, cost value
And I want to output the TOP 10 costs values with the name, which is no problem, BUT: as 11th row, I want to output all others sum as "Others" marked ... Is that possible with a SQL query?
I hope you understand my question and I'm very thankful for all helpful answers.
Best regards,
Tobias
UPDATE:
<< Data Example >>
Please try:
;with T as(
select *, ROW_NUMBER() over (order by value desc) RNum
from YourTable
)
select value, name from T
where RNum<=10
union all
select sum(value), 'Others'
from T
where RNum>10
Perhaps something like this?
select * from (select top (10) name, value from costs order by value) s1
UNION (
select 'other', sum(value) from costs
where name not in (select top 10 Name from costs order by value)
)
This assumes Name is a PK on costs.
;with CTE as(SELECT Name ,
value ,row_number() OVER (ORDER BY Name) AS RowNumber FROM #Temp )
select Name,value
from cte
Where RowNumber<11
union
select 'Other',Sum(value)
from cte
Where RowNumber>=11
Sample Fiddle