SQL Server : select latest time - sql-server

I have a query that works well but has one problem, it displays other data I don't want.
The data is the latest of each username.
Here is the query:
SELECT
l.USER_KEY AS id,
l.USER_ID AS username,
gl1.CHAR_KEY AS char_id,
gl1.NAME AS charname,
gl1.GATENUM AS server,
CONVERT(VARCHAR(20), l.LOGINTIME, 100) AS user_time,
CONVERT(VARCHAR(20), gl1.OCCUR_TIME, 100) AS char_time
FROM LOG_CONNECT201211 AS gl1
JOIN game.dbo.CHAR_INFOR AS g --character data
ON gl1.CHAR_KEY = g.CHAR0_KEY OR gl1.CHAR_KEY = g.CHAR1_KEY OR gl1.CHAR_KEY = g.CHAR2_KEY
JOIN login.dbo.USER_CHECK_LOGIN AS l --login data
ON g.USER_KEY = l.USER_KEY
JOIN (SELECT char_key, max(OCCUR_TIME) as mostrecent --game logs
FROM LOG_CONNECT201211
WHERE KIND=20 OR KIND=21
GROUP BY char_key) AS gl2
ON gl2.char_key = gl1.char_key and gl2.mostrecent = gl1.OCCUR_TIME
WHERE l.CHECKLOGIN = 1
ORDER BY username DESC
That returns:
id username char_id name map user_time char_time
------------------------------------------------------------------------------------
3667 zr5970 11002 warpath 4 Nov 15 2012 8:54AM Nov 7 2012 6:31AM
3667 zr5970 11004 bloodfines 4 Nov 15 2012 8:54AM Nov 7 2012 6:33AM
3667 zr5970 11003 hanzhou 1 Nov 15 2012 8:54AM Nov 15 2012 8:54AM
14999 yvacosta 52086 Creams 1 Nov 15 2012 8:17AM Nov 15 2012 8:17AM
23433 yurich 1911481 abal 5 Nov 15 2012 8:34AM Nov 9 2012 4:05PM
23433 yurich 1911482 yurich 5 Nov 15 2012 8:34AM Nov 15 2012 8:30AM
23433 yurich 1911483 sharmaine 5 Nov 15 2012 8:34AM Nov 15 2012 8:35AM
10967 yubiwamoi 33376 Dwina 1 Nov 15 2012 4:33AM Nov 15 2012 4:33AM
So the data is correct, but I only want to return one row per username.
On this data the username returns 3, with 3 names, but the only name I want is that one with the latest char_time.
Example correct data:
id username char_id name map user_time char_time
-----------------------------------------------------------------------------------
3667 zr5970 11003 hanzhou 1 Nov 15 2012 8:54AM Nov 15 2012 8:54AM
14999 yvacosta 52086 Creams 1 Nov 15 2012 8:17AM Nov 15 2012 8:17AM
23433 yurich 1911483 sharmaine 5 Nov 15 2012 8:34AM Nov 15 2012 8:35AM
10967 yubiwamoi 33376 Dwina 1 Nov 15 2012 4:33AM Nov 15 2012 4:33AM
Notice that I only displayed the data for zr5970 with the latest char_time
Please advice, Thank you.

Use ROW_NUMBER()
SELECT *
FROM
(
SELECT
l.USER_KEY AS id,
l.USER_ID AS username,
gl1.CHAR_KEY AS char_id,
gl1.NAME AS charname,
gl1.GATENUM AS server,
CONVERT(VARCHAR(20), l.LOGINTIME, 100) AS user_time,
CONVERT(VARCHAR(20), gl1.OCCUR_TIME, 100) AS char_time,
rn = row_number() over (partition by l.USER_KEY order by gl1.OCCUR_TIME DESC)
FROM LOG_CONNECT201211 AS gl1
JOIN game.dbo.CHAR_INFOR AS g --character data
ON gl1.CHAR_KEY = g.CHAR0_KEY OR gl1.CHAR_KEY = g.CHAR1_KEY OR gl1.CHAR_KEY = g.CHAR2_KEY
JOIN login.dbo.USER_CHECK_LOGIN AS l --login data
ON g.USER_KEY = l.USER_KEY
WHERE l.CHECKLOGIN = 1
) X
WHERE rn=1
ORDER BY username DESC

First select just the user name and the max time. This way you will have the correct number of rows. When you have that you can easily the other columns to your query...

select a.USER_KEY AS id,
l.USER_ID AS username,
gl1.CHAR_KEY AS char_id,
gl1.NAME AS charname,
gl1.GATENUM AS server,
CONVERT(VARCHAR(20), l.LOGINTIME, 100) AS user_time,
CONVERT(VARCHAR(20), gl1.OCCUR_TIME, 100) AS char_time
from
(select user_key, max(occur_time) as mostrecent
from log_connect2011
WHERE KIND=20 OR KIND=21
group by user_key) a
join LOG_CONNECT201211 AS gl1 on a.user_key = gl1.user_key and a.mostrecent = gl1.occur_time
JOIN game.dbo.CHAR_INFOR AS g --character data
ON gl1.CHAR_KEY = g.CHAR0_KEY OR gl1.CHAR_KEY = g.CHAR1_KEY OR gl1.CHAR_KEY = g.CHAR2_KEY
JOIN login.dbo.USER_CHECK_LOGIN AS l --login data
ON g.USER_KEY = l.USER_KEY
WHERE l.CHECKLOGIN = 1
ORDER BY username DESC

Related

Data year wise sql

I try to get data year wise. I tried this query
select
year(SStartDate) as joinedyear ,
count(*) joined_total
from
Detail
where
client = 81
Group By
YEAR(StartDate)
union all
select
year(SEndDate) as leftyear,
count(*) left_total
from
Detail
where
client = 81
Group By
YEAR(SEndDate)
This shows correct data but this shows data like this
1900 12
2001 1
2012 3
2013 3
2016 45
1900 23
2002 34
2004 34
2015 1
2016 56
where as I want data like this
joinedyear joined_total leftyear left_total
1900 12 1900 45
2001 1 2002 34
2012 3 2004 34
2013 3 2015 1
2016 45 2016 56
Try This below query..it mat help you
select * from (
select year(SStartDate) as joinedyear ,
count(*) joined_total from Detail
where client=81
Group By YEAR(StartDate)
) as a
full outer join
(
select year(SEndDate) as leftyear , count(*) left_total from Detail
where client=81
Group By YEAR(SEndDate)
) as b
on a.joinedyear=b.leftyear

sql crosstab for graphing data output

I am trying to get a crosstab of data so that the columns are months of the year and the rows are the years themselves based on value sold in that month.
Therefore:
year jan feb mar apr etc
2014 0 1 5 9
2015 11 12 0 14
using this SQL - (excuse the crudeness)
SELECT distinct
case
when year(fsivho.InvoiceDate) = 2014 then 2014
when year(fsivho.InvoiceDate) = 2015 then 2015
when year(fsivho.InvoiceDate) = 2016 then 2016
when year(fsivho.InvoiceDate) = 2017 then 2017
when year(fsivho.InvoiceDate) = 2018 then 2018
when year(fsivho.InvoiceDate) = 2019 then 2019
when year(fsivho.InvoiceDate) = 2020 then 2020
when year(fsivho.InvoiceDate) = 2021 then 2021
when year(fsivho.InvoiceDate) = 2022 then 2022
when year(fsivho.InvoiceDate) = 2023 then 2023
when year(fsivho.InvoiceDate) = 2024 then 2024
when year(fsivho.InvoiceDate) = 2025 then 2025
end as Month1,
(select sum(cast(fsivl.ShipQuantity * fsivl.InvoiceLocalUnitPrice as decimal(8,2))) as Value
from sqlinvline fsivl , sqlinvheaher fsivh
where fsivl.HeaderKey = fsivh.HeaderKey
and fsivh.InvoiceType = 'I'
and year(fsivh.InvoiceDate)* 100 + month(fsivh.InvoiceDate)
= year(fsivho.InvoiceDate)* 100 + month(fsivho.InvoiceDate)
and MONTH(fsivh.InvoiceDate) = 1
) as 'Jan',
(select sum(cast(fsivl.ShipQuantity * fsivl.InvoiceLocalUnitPrice as decimal(8,2))) as Value
from sqlinvline fsivl , sqlinvheaher fsivh
where fsivl.HeaderKey = fsivh.HeaderKey
and fsivh.InvoiceType = 'I'
and year(fsivh.InvoiceDate)* 100 + month(fsivh.InvoiceDate)
= year(fsivho.InvoiceDate)* 100 + month(fsivho.InvoiceDate)
and MONTH(fsivh.InvoiceDate) = 2
) as 'Feb',
from sqlinvline fsivlo , sqlinvheader fsivho
where fsivlo.HeaderKey = fsivho.InvoiceHeaderKey
and fsivho.InvoiceType = 'I'
and year(fsivho.InvoiceDate) >= year(DATEadd(yyyy, -2, GETDATE()))
group by YEAR(fsivho.InvoiceDate)
order by Month1
(I've shortened the code for brevity but the other months are formatted the same way)
When I run it, I get multiple lines for the years with an entry for a value against each month and the rest as nulls...e.g.
year jan feb mar apr etc
2014 nul 1 nul nul
2014 6 nul nul nul
2014 nul nul 7 nul
etc
What am I doing wrong?
all sorted by rewriting the query after many hours looking at pivot examples.
SELECT * from
(select year(fsivho.InvoiceDate) as Yr, cast(datename(MONTH ,fsivho.InvoiceDate) as CHAR(3)) as Mth,
cast(fsivlo.ShipQuantity * fsivlo.InvoiceLocalUnitPrice as decimal(8,2)) as Value
from ARInvoiceLine fsivlo , ARInvoiceHeader fsivho
where fsivlo.HeaderKey = fsivho.HeaderKey
and fsivho.InvoiceType = 'I'
and year(fsivho.InvoiceDate) >= year(DATEadd(yyyy, -4, GETDATE()))) src
PIVOT
(sum(Value)
for Mth in ([Jan],[Feb],[Mar],[Apr],[May],[Jun],[Jul],[Aug],[Sep],[Oct],[Nov],[Dec])) as pvt
order by Yr;
so now have rows of years with months across the top and values in the correct place!

Get last 6 months monthname.month number and Years in simple select statement

How to get last 6 months month name, month number and Years in simple select statement in sqlserver .
The no of months is 6, and is fixed
12 Dec 2015
11 Nov 2015
10 Oct 2015
9 Sep 2015
8 Aug 2015
7 Jul 2015
6 Jun 2015
This should handle year end boundaries
say, if the current month is Feb 2016, the result should give 2015 months.
2 Feb 2016
1 Jan 2016
12 Dec 2015
11 Nov 2015
10 Oct 2015
9 Sep 2015
8 Aug 2015
You can do it with the following:
SELECT MONTH(DATEADD(mm, -m, GETDATE())) AS m,
LEFT(DATENAME(mm, DATEADD(mm, -m, GETDATE())), 3) AS n,
YEAR(DATEADD(mm, -m, GETDATE())) AS y
FROM (VALUES (0),(1),(2),(3),(4),(5),(6)) t(m)
Output:
m n y
12 Dec 2015
11 Nov 2015
10 Oct 2015
9 Sep 2015
8 Aug 2015
7 Jul 2015
6 Jun 2015
Try this
;with cte as
(
select 0 as num
union all
select num+1 from cte where num<6
)
select month(dates),datename(month,dates),year(dates)
from
(
select dateadd(mm,-num,datadd(dd,1,eomonth(getdate(),-1))) as dates
from cte
) A
SQL FIDDLE DEMO
select datepart(m,GETDATE()) MonthNumber,left(datename(month,GETDATE()),3) as Month,year(GETDATE()) as Year union all
select datepart(m,DATEADD(month,-1,GETDATE())) MonthNumber,left(datename(month,DATEADD(month,-1,GETDATE())),3) as Month,year(DATEADD(month,-1,GETDATE())) as Year union all
select datepart(m,DATEADD(month,-2,GETDATE())) MonthNumber,left(datename(month,DATEADD(month,-2,GETDATE())),3) as Month,year(DATEADD(month,-2,GETDATE())) as Year union all
select datepart(m,DATEADD(month,-3,GETDATE())) MonthNumber,left(datename(month,DATEADD(month,-3,GETDATE())),3) as Month,year(DATEADD(month,-3,GETDATE())) as Year union all
select datepart(m,DATEADD(month,-4,GETDATE())) MonthNumber,left(datename(month,DATEADD(month,-4,GETDATE())),3) as Month,year(DATEADD(month,-4,GETDATE())) as Year union all
select datepart(m,DATEADD(month,-5,GETDATE())) MonthNumber,left(datename(month,DATEADD(month,-5,GETDATE())),3) as Month,year(DATEADD(month,-5,GETDATE())) as Year union all
select datepart(m,DATEADD(month,-6,GETDATE())) MonthNumber,left(datename(month,DATEADD(month,-6,GETDATE())),3) as Month,year(DATEADD(month,-6,GETDATE())) as Year
The above query will work for most of the RDBMS.
For SQL Server specific use the below query.
SELECT MONTH(DATEADD(month, -month, GETDATE())) AS MonthNumber ,
LEFT(DATENAME(MONTH, DATEADD(month, -month, GETDATE())), 3) AS MonthName,
YEAR(DATEADD(month, -month, GETDATE())) AS Year
FROM ( VALUES (0), (1), (2), (3), (4), (5),(6) ) t ( month )
Try DATEADD:
Select * FROM Table where YourDate>=DATEADD(m, -6, GETDATE())

Format date to include day of week

I have a SQL Server 2012 query that converts date to VARCHAR
SELECT
CONVERT(VARCHAR(12), dbo.Download.Date_of_Download, 107) as Date_to_Display,
dbo.Download.Number_of_Computers
FROM dbo.Download
ORDER BY dbo.Download.Date_of_Download DESC
Below are results
Date_to_Display Number_of_Computers
-----------------------------------
Aug 14, 2014 240
Aug 13, 2014 519
Aug 12, 2014 622
Aug 11, 2014 2132
Aug 10, 2014 1255
Aug 09, 2014 3240
How do I include day of week, i.e. Saturday, Aug 09, 2014 ?
try this:
select datename(dw,getdate())
output:
------------------------------
Thursday
(1 row(s) affected)
using your query:
SELECT
Datename(dw, dbo.Download.Date_of_Download)+', '+CONVERT(VARCHAR(12), dbo.Download.Date_of_Download, 107) as Date_to_Display,
dbo.Download.Number_of_Computers
FROM dbo.Download
ORDER BY dbo.Download.Date_of_Download DESC
In SQL Server version 2012 and later, there is the FORMAT TSQL function that can do what you want. The "dddd" portion does day of the week:
SELECT
FORMAT(dbo.Download.Date_of_Download, 'dddd MMM dd, yyyy') as Date_to_Display,
dbo.Download.Number_of_Computers
FROM dbo.Download
ORDER BY dbo.Download.Date_of_Download DESC
MS docs: https://learn.microsoft.com/en-us/sql/t-sql/functions/format-transact-sql

Sql Server Query Result By Week

I have following tables
Order
ID OrderDate Quantity Item
1 1 jan 2012 5 A
2 6 jan 2012 10 A
3 9 jan 2012 3 B
4 16 jan 2012 2 C
Order Shipped
ID SuppliedOn Quantity Item OrderId
1 7 Jan 2012 3 A 1
2 9 Jan 2012 2 A 1
3 9 Jan 2012 10 A 2
4 17 jan 2012 3 B 3
I want to list order got and order supplied by week
like
Week Total_Order_got Total_Order_Supplied Item
1st week Jan(2 jan 2012) 15 3 A
2nd Week Jan(9 jan 2012) 0 12 A
2nd Week Jan(9 jan 2012) 3 0 B
3rd Week Jan(16 jan 2012) 0 3 B
3rd Week Jan(16 jan 2012) 2 0 C
Here is the solution:
Select my.Mydate, MAX(ThisWeekStart) as ThisWeekStart , SUM(oqty) as oqty,SUM(sqty) as sqty,item from
(Select DatePart(week,o.orderdate) as Mydate,
dateadd(wk, datediff(wk, 0, o.orderdate), 0) as ThisWeekStart,
o.qty as oqty, 0 as sqty, o.item
FROM [order] o
UNION
SELECT DatePart(week,s.suppliedon) as suppliedon,
dateadd(wk, datediff(wk, 0, s.suppliedon), 0) as ThisWeekStart,
0 as oqty, s.qty as sqty, s.item
FROM supply s) as my
GROUP BY my.Mydate, item
Let me know whether it worked for you.

Resources