Add other column (time) to DISTINCT rows - sql-server

I am selecting unique rows with
SELECT DISTINCT
LogContent
FROM
[WebAppLog] WITH (NOLOCK)
WHERE
LogName = 'frontendErrorLog'
But how to pair result with other column? I want to select unique LogName and assign it corresponding earliest LogTime just like in:
SELECT
LogTime, LogContent
FROM
[WebAppLog] WITH (NOLOCK)
WHERE
LogName = 'frontendErrorLog'

#Ultra
Will a grouping work for you, like this.
SELECT LogContent,MAX(LogTime) LogTime
FROM [WebAppLog] WITH (NOLOCK)
WHERE LogName = 'frontendErrorLog'
GROUP BY LogContent

You can use ROW_NUMBER:
WITH CTE AS
(
SELECT LogTime, LogContent,
rn = ROW_NUMBER() OVER (PARTITION BY LogContent ORDER BY LogTime ASC)
FROM [WebAppLog] WITH (NOLOCK)
WHERE LogName = 'frontendErrorLog'
)
SELECT LogTime, LogContent FROM CTE WHERE rn = 1

Related

How do I select the top 1 results of the if the same identifier exist? SQL Server

I have a data table in sql server 2008 that I would like to select the top 1 out of each identifier:
The results shld looks like this during before and after:
Thus it should only select the 1st results if the same identifier do exist. Thanks a lot.
select distinct [Primary Identifier] from tbl
If you have entire records (other columns) instead of that single column, you can row number them and choose one.
select {list of columns}
from
(
select *, rn = row_number over (partition by [Primary Identifier]
order by 1/0)
from tbl
) X
where rn = 1;
order by 1/0 is arbitrary. If you need to choose a specific one from the "duplicates", for example the highest cost, you order by cost descending, i.e.
(partition by [Primary Identifier]
order by [cost] descending)
Just distinct them:
select distinct [primary identifier] from tablename
Or by grouping:
select [primary identifier] from tablename group by [primary identifier]
If more columns exist you can rank rows with window function:
;with cte as(select *, row_number() over(partition by [primary identifier] order by (select null)) rn from tablename)
select * from cte where rn = 1
Change order by (select null) to appropriate ordering column.
i think this will be an appropriate solution to your need-
;WITH cte AS
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY [Primary Identifier] ORDER BY [sort columns]) AS rowid
FROM [table]
)
SELECT *
FROM cte
WHERE rowid = 1

Select Multiple Columns join SQL Server

I have an Employee table like this
And a second table for EmployeeComments with the EmployeeID as foreign key:
I would like to query the employees with their comments in the following format:
select Name, Comment
from Employee emp
left join EmployeeComments empC on empC.EmployeeID = emp.ID
I would like the results to be like:
I have already looked at Pivot, but it doesn't resolve my issue
Use window function:
select case when row_number() over(partition by emp.name order by empC.ID) = 1
then Name
else '' end as Name,
Comment
from Employee emp
left join EmployeeComments empC On empC.EmployeeID = emp.ID
This might give you some kind of order in your result window at least
WITH cte AS(
SELECT emp.Name ,
empC.Comment,
RANK() OVER (ORDER BY emp.Name) NameOrder,
ROW_NUMBER() OVER (PARTITION BY emp.Name ORDER BY empC.ID) RN
FROM Employee emp
LEFT JOIN EmployeeComments empC ON empC.EmployeeID = emp.ID
)
SELECT
Name = (CASE WHEN RN = 1 THEN Name ELSE '' END),
Comment
FROM
cte
ORDER BY
NameOrder,
RN
"use Cross Join:"
Query:
select case t.cnt
when 1 then
coalesce(t.Name,' ')
end as Name,t.comment
from
(
select t1.Name,t2.comment,row_number()
over(partition by t1.name order by t1.Name)
as cnt
from
EmployeeComments t1
cross join
Employee t2
where t1.ID=t2.Employeeid
)t

How to get rows with Maximum id with condition of a table in SQL Server

i have a table similar this
id-value-RowInid
1-xy-1
1-xx-2
1-xz-3
2-xx-1
2-xr-2
3-xq-1
4-xa-1
4-xc-2
...
i need a function for this table with similar output to get maximum of RowInid in separated id group
1-xz-3
2-xr-2
3-xq-1
4-xc-2
...
You just need to use MAX(RowInid) with GROUP BY Id, value
SELECT ID, VALUE, MAX(RowInid) FROM myTable GROUP BY ID, VALUE
EDIT:
As you updated your question, you can get value field using sub-query like this:
SELECT ID, VALUE, RowInid
FROM myTable t1 WHERE RowInid =
(
SELECT MAX(RowInid) FROM myTable WHERE id = t1.id GROUP BY id
)
ORDER BY id ASC;
You can also achieve this using INNER JOIN like this:
SELECT t2.ID, VALUE, t2.RowInid FROM myTable t1
INNER JOIN
(
SELECT ID, MAX(RowInid) AS RowIniD FROM myTable GROUP BY ID
) AS t2
ON t1.ID = t2.ID AND t1.RowInid = t2.RowInid
ORDER BY t1.ID ASC;
See this SQLFiddle
See more about GROUP BY and MAX in SQL Server.
no need for group by or max at all
select id, value, rowinid from
( select *, row_number() over (partition by id, order by rowinid desc) rn from yourtable ) v
where rn = 1
Try with,
Use Sub Query to get Id, Value and Max RowInid,
SELECT m1.[Id],m1.Value, m1.RowInid
FROM [Practice].[dbo].[myTable] m1 WHERE RowInid = (SELECT MAX(m2.RowInid) FROM [Practice].[dbo].[myTable] m2 WHERE M1.Id = m2.Id GROUP BY Id)
above query return result like:
4-xx-2
3-xx-1
2-xx-2
1-xx-3
To Ascending this use,
SELECT m1.[id],m1.Value, m1.RowInid
FROM [Practice].[dbo].[myTable] m1 WHERE m1.RowInid = (SELECT MAX(m2.RowInid) FROM [Practice].[dbo].[myTable] m2 WHERE M2.id = m1.id GROUP BY id) ORDER BY m1.id ASC

RANK() Over Partition BY not working

When I run the code below the ROWID is always 1.
I need to the ID to start at 1 for each item with the same Credit Value.
;WITH CTETotal AS (SELECT
TranRegion
,TranCustomer
,TranDocNo
,SUM(TranSale) 'CreditValue'
FROM dbo.Transactions
LEFT JOIN customers AS C
ON custregion = tranregion
AND custnumber = trancustomer
LEFT JOIN products AS P
ON prodcode = tranprodcode
GROUP BY
TranRegion
,TranCustomer
,TranDocNo)
SELECT
r.RegionDesc
,suppcodedesc
,t.tranreason as [Reason]
,t.trandocno as [Document Number]
,sum(tranqty) as Qty
,sum(tranmass) as Mass
,sum(transale) as Sale
,cte.CreditValue AS 'Credit Value'
,RANK() OVER (PARTITION BY cte.CreditValue ORDER BY cte.CreditValue)AS ROWID
FROM transactions t
LEFT JOIN dbo.Regions AS r
ON r.RegionCode = TranRegion
LEFT JOIN CTETotal AS cte
ON cte.TranRegion = t.TranRegion
AND cte.TranCustomer = t.TranCustomer
AND cte.TranDocNo = t.TranDocNo
GROUP BY
r.RegionDesc
,suppcodedesc
,t.tranreason
,t.trandocno
,cte.CreditValue
ORDER BY CreditValue ASC
EDIT
All the credit values with 400 must have the ROWID set to 1. And all the credit values with 200 must have the ROWID set to 2. And so on and so on.
Do you need something like this?
with cte (item,CreditValue)
as
(
select 'a',8 as CreditValue union all
select 'b',18 union all
select 'a',8 union all
select 'b',18 union all
select 'a',8
)
select CreditValue,dense_rank() OVER (ORDER BY item)AS ROWID from cte
Result
CreditValue ROWID
----------- --------------------
8 1
8 1
8 1
18 2
18 2
In your code replace
,RANK() OVER (PARTITION BY cte.CreditValue ORDER BY cte.CreditValue)AS ROWID
by
,DENSE_RANK() OVER (ORDER BY cte.CreditValue)AS ROWID
You just don't have to use PARTITION, just DENSE_RANK() OVER (ORDER BY cte.CreditValue)
I think the problem is with the RANK() OVER (PARTITION BY clause
you have to partition it by item not by CreditValue
Try this
RANK() OVER (PARTITION BY cte.CreditValue ORDER BY cte.RegionDesc)AS ROWID
Edit: The issue here isn't actually the nesting of the subquery, it's potentially based on partition by having columns that truly make each row unique (or 1)
Rather than ranking within your complex query like this
select
rank() over(partition by...),
*
from
data_source
join table1
join table2
join table3
join table4
order by
some_column
Try rank() or row_number() on the resulting data set, not within it.
For example, using the query above, remove rank() and implement it this way:
select
rank() over(partition by...),
results.*
from (
select
*
from
data_source
join table1
join table2
join table3
join table4
order by
some_column
) as results

select top 1 with a group by

I have two columns:
namecode name
050125 chris
050125 tof
050125 tof
050130 chris
050131 tof
I want to group by namecode, and return only the name with the most number of occurrences. In this instance, the result would be
050125 tof
050130 chris
050131 tof
This is with SQL Server 2000
I usually use ROW_NUMBER() to achieve this. Not sure how it performs against various data sets, but we haven't had any performance issues as a result of using ROW_NUMBER.
The PARTITION BY clause specifies which value to "group" the row numbers by, and the ORDER BY clause specifies how the records within each "group" should be sorted. So partition the data set by NameCode, and get all records with a Row Number of 1 (that is, the first record in each partition, ordered by the ORDER BY clause).
SELECT
i.NameCode,
i.Name
FROM
(
SELECT
RowNumber = ROW_NUMBER() OVER (PARTITION BY t.NameCode ORDER BY t.Name),
t.NameCode,
t.Name
FROM
MyTable t
) i
WHERE
i.RowNumber = 1;
select distinct namecode
, (
select top 1 name from
(
select namecode, name, count(*)
from myTable i
where i.namecode = o.namecode
group by namecode, name
order by count(*) desc
) x
) as name
from myTable o
SELECT max_table.namecode, count_table2.name
FROM
(SELECT namecode, MAX(count_name) AS max_count
FROM
(SELECT namecode, name, COUNT(name) AS count_name
FROM mytable
GROUP BY namecode, name) AS count_table1
GROUP BY namecode) AS max_table
INNER JOIN
(SELECT namecode, COUNT(name) AS count_name, name
FROM mytable
GROUP BY namecode, name) count_table2
ON max_table.namecode = count_table2.namecode AND
count_table2.count_name = max_table.max_count
I did not try but this should work,
select top 1 t2.* from (
select namecode, count(*) count from temp
group by namecode) t1 join temp t2 on t1.namecode = t2.namecode
order by t1.count desc
Here are to examples that you could use but the temp table use is more efficient than the view, but was done on a small data sample. You would want to check your own statistics.
--Creating A View
GO
CREATE VIEW StateStoreSales AS
SELECT t.state,t.stor_id,t.stor_name,SUM(s.qty) 'TotalSales'
,ROW_NUMBER() OVER (PARTITION BY t.state ORDER BY SUM(s.qty) DESC) AS 'Rank'
FROM [dbo].[sales] s
JOIN [dbo].[stores] t ON (s.stor_id = t.stor_id)
GROUP BY t.state,t.stor_id,t.stor_name
GO
SELECT * FROM StateStoreSales
WHERE Rank <= 1
ORDER BY TotalSales Desc
DROP VIEW StateStoreSales
---Using a Temp Table
SELECT t.state,t.stor_id,t.stor_name,SUM(s.qty) 'TotalSales'
,ROW_NUMBER() OVER (PARTITION BY t.state ORDER BY SUM(s.qty) DESC) AS 'Rank' INTO #TEMP
FROM [dbo].[sales] s
JOIN [dbo].[stores] t ON (s.stor_id = t.stor_id)
GROUP BY t.state,t.stor_id,t.stor_name
SELECT * FROM #TEMP
WHERE Rank <= 1
ORDER BY TotalSales Desc
DROP TABLE #TEMP

Resources