SQL change day in my language in select statement - sql

How can I change the day in my language with a select statement like use if:
if day= sunday then set day = minggu

You need some kind of conversion. Take a look at example below:
WITH Src AS
(
SELECT * FROM (VALUES
(GETDATE()),
(DATEADD(DAY, 1, GETDATE())),
(DATEADD(DAY, 2, GETDATE())),
(DATEADD(DAY, 3, GETDATE())),
(DATEADD(DAY, 4, GETDATE())),
(DATEADD(DAY, 5, GETDATE())),
(DATEADD(DAY, 6, GETDATE()))
) T(Dates)
)
SELECT
FORMAT(Dates, 'ddd', 'id-ID') LocalizedFormat,
SUBSTRING('MingguSen Sel Rabu Kamis Jumat Sabtu ', 6*(DATEPART(WEEKDAY,Dates)-1)+1, 6) LocalizedExpression
FROM Src
It results in:
LocalizedFormat LocalizedExpression
--------------- -------------------
Kamis Kamis
Jumat Jumat
Sabtu Sabtu
Minggu Minggu
Sen Sen
Sel Sel
Rabu Rabu

Are you looking for an update statement? Because you have a SET in your select statement. If so, how about this?
UPDATE table_name
SET datecol = CASE
WHEN DATENAME(dw, datecol) = 'Monday' THEN 'Minggu'
WHEN DATENAME(dw, datecol) = 'Tuesday'
...
ELSE datecol
END;

Related

How to get the last sunday of the year using TSQL?

I need to check if a given day is the last sunday of any year, if yes the return 1 using TSQL only.
I do not have much idea about TSQL.
SQL Server has a problem with weekdays, because they can be affected by internationalization settings. Assuming the defaults, you can do:
select dateadd(day,
1 - datepart(weekday, datefromparts(#year, 12, 31)),
datefromparts(#year, 12, 31)
)
Otherwise, you'll need to do a case expression to turn the day of the week into a number.
In an older version of SQL Server, you could do:
select dateadd(day,
1 - datepart(weekday, cast(#year + '0101' as date)),
cast(#year + '0101' as date)
)
I haven't worked with tsql specifically but if my sql knowledge and googling is good enough then something like this should do the trick:
... WHERE DATEPART(dw, date) = 7 and DATEDIFF (d, date, DATEFROMPARTS (DATEPART(yyyy, date), 12, 31)) <= 6
Basically we check if that day is Sunday at first and then if it's less than week away from last day of the year
Using Mr. Gordon's query, following IIF() returns 1 if given day is last Sunday of the year, returns 0 if it is not.
Using 2018 as year and 2018-12-30 as given date. You can replace values with variables.
select IIF( DATEDIFF(DAY,'2018-12-30',
DATEADD(day,
1 - datepart(weekday, datefromparts(2018, 12, 31)),
datefromparts(2018, 12, 31)
)) = 0, 1, 0)
You can use this function
Function Code :
create FUNCTION CheckIsSaturday
(
#date DATETIME
)
RETURNS int
AS
BEGIN
-- Declare the return variable here
DECLARE #result INT
DECLARE #DayOfWeek NVARCHAR(22)
DECLARE #LastDayOfYear DATETIME
select #LastDayOfYear=DATEADD(yy, DATEDIFF(yy, 0, #date) + 1, -1)
SELECT #DayOfWeek=DATENAME(dw, #date)
IF(#DayOfWeek='Saturday' AND DATEDIFF(dd,#date,#LastDayOfYear)<7)
RETURN 1;
RETURN 0;
END
GO
function Usage:
SELECT dbo.CheckIsSaturday('2017-12-23')
This becomes quite trivial if you have a Calendar Table
DECLARE #CheckDate DATE = '20181230'
;WITH cteGetDates AS
(
SELECT
[Date], WeekDayName, WeekOfMonth, [MonthName], [Year]
,LastDOWInMonth = ROW_NUMBER() OVER
(
PARTITION BY FirstDayOfMonth, [Weekday]
ORDER BY [Date] DESC
)
FROM
dbo.DateDimension
)
SELECT * FROM cteGetDates D
WHERE D.LastDOWInMonth = 1 AND D.WeekDayName = 'Sunday' and D.MonthName = 'December' AND D.[Date] = #CheckDate
You can also use this one to get every last day of the year:
;WITH getlastdaysofyear ( LastDay, DayCnt ) AS (
SELECT DATEADD(dd, -DAY(DATEADD(mm, 1, DATEADD(yy, DATEDIFF(yy, 0, GETDATE()) + 1, -1))),
DATEADD(mm, 1, DATEADD(yy, DATEDIFF(yy, 0, GETDATE()) + 1, -1))),
0 AS DayCnt
UNION ALL
SELECT LastDay,
DayCnt + 1
FROM getlastdaysofyear
)
SELECT *
FROM ( SELECT TOP 7 DATEADD(DD, -DayCnt, LastDay) LastDate,
'Last ' + DATENAME(Weekday,DATEADD(DD, -DayCnt, LastDay)) AS DayStatus
FROM getlastdaysofyear ) T
ORDER BY DATEPART(Weekday, LastDate)
Hope you like it :)

SQL setting start date to Friday, and read Data between 2 dates

I'm trying to set the start date to friday on a sql query. Which I have done as you can see below. What I need to do now is show all the GameID's between Friday and Saturday, and it refreshes every week (so that every week it shows other games that have been played in that week).
I'm a complete beginner at SQL so any help is greatly appreciated!
I have tried the sql query below.
DECLARE #StartFriday datetime
DECLARE #EndSaturday datetime
SET DATEFIRST 6 -- Set the start of the week to Friday
SELECT *
FROM
(
SELECT GameDate,
DATEADD(w, 0, DATEADD(w, DATEDIFF(w, 0,GETDATE()), -5)) AS 'StartFriday',
DATEADD(w, 0, DATEADD(w, DATEDIFF(w, 0,GETDATE()), 1)) AS 'EndSaturday'
FROM VW_Resultaat_Score
WHERE GameDate BETWEEN 'StartFriday' AND 'EndSaturday' --Show all GameDates between #StartFriday and #EndSaturday
)
I would love any help I can get!
Cheers
Perhaps this will work better:
DECLARE #StartFriday datetime
DECLARE #EndSaturday datetime
SET DATEFIRST 6
Set #StartFriday = DATEADD(w, 0, DATEADD(w, DATEDIFF(w, 0,GETDATE()), -5))
Set #EndSaturday = DATEADD(w, 0, DATEADD(w, DATEDIFF(w, 0,GETDATE()), 1))
SELECT *
FROM
(
SELECT GameDate
FROM VW_Resultaat_Score
WHERE GameDate BETWEEN #StartFriday AND #EndSaturday
)
If you will only ever need the weekend previous, this code will work:
SELECT *
FROM VW_Resultaat_Score
WHERE GameDate BETWEEN
(SELECT DATEADD(d, 1 - datepart(weekday, dateadd(d, 2, getdate())), getdate()))
AND
(SELECT DATEADD(d, 1 - datepart(weekday, dateadd(d, 1, getdate())), getdate()))
Code looks a little crazy, but it works. If you may need to query other specific weekends, this may be an option:
DECLARE #getdate date
SET #getdate='2017-05-16'
SELECT *
FROM VW_Resultaat_Score
WHERE GameDate BETWEEN
(SELECT DATEADD(d, 1 - datepart(weekday, dateadd(d, 2, #getdate)), #getdate))
AND
(SELECT DATEADD(d, 1 - datepart(weekday, dateadd(d, 1, #getdate)), #getdate))
Taking it a step further, you may need to report on each of these weekends. The following code gives you all the Friday Saturdays of each week for 2017.
WITH Fri as
(SELECT DATEPART(YEAR,DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), n.num)) yyyy, DATEPART(wk,DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), n.num)) weeknumber, Fridays = CAST(DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), n.num) as Date)
FROM (SELECT TOP 366 num = ROW_NUMBER() OVER(ORDER BY a.NAME)-1 FROM dbo.syscolumns a, dbo.syscolumns b) n
WHERE DATENAME(weekday, DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), n.num)) = 'Friday')
,
Sat as
(SELECT weeknumber=DATEPART(wk,DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), n.num)), Saturdays = CAST(DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), n.num) as Date)
FROM (SELECT TOP 366 num = ROW_NUMBER() OVER(ORDER BY a.NAME)-1 FROM dbo.syscolumns a, dbo.syscolumns b) n
WHERE DATENAME(weekday, DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), n.num)) = 'Saturday')
Select Fri.weeknumber, fri.yyyy, Fridays, Saturdays
FROM Fri
JOIN Sat on Fri.weeknumber=Sat.weeknumber

How to get list of 2nd and 4th Saturday dates in SQL Server?

I am almost a newbie to writing SQL queries.
In the context of SQL Server, how to get list of 2nd and 4th Saturday dates
in the year 2016?
Done as a derived table simply to show the logic but you can reduce if you prefer:
select *
from (
select d2016,
datename( weekday, d2016 ) as wkdy,
row_number( ) over ( partition by datepart( month, d2016 ), datename( weekday, d2016 ) order by d2016 ) as rn_dy_mth
from (
select dateadd( day, rn, cast( '2016-01-01' as date ) ) as d2016
from (
select row_number() over( order by object_id ) - 1 as rn
from sys.columns
) as rn
) as dy
) as dy_mth
where rn_dy_mth in ( 2, 4 )
and wkdy = 'Saturday'
order by d2016
--DEFINE LIMITS FOR DAY
DECLARE #TODATE DATETIME, #FROMDATE DATETIME
SET #FROMDATE ='2010-01-01'
SET #TODATE = '2017-12-31'
;WITH DATESEQUENCE( [DATE] ) AS
(
SELECT #FROMDATE AS [DATE]
UNION ALL
SELECT DATEADD(DAY, 1, [DATE])
FROM DATESEQUENCE
WHERE DATE < #TODATE
)
, DATESATURDAY AS
(SELECT CAST(CAST(YEAR([DATE]) AS VARCHAR)+
(CASE WHEN DATEPART(M,[DATE])<=9 THEN '0'+CAST(DATEPART(M,[DATE]) AS VARCHAR)
ELSE CAST(DATEPART(M,[DATE]) AS VARCHAR) END ) AS NUMERIC) AS MONTH_ID
,CONVERT(VARCHAR,[DATE],106) AS DAY_DESC
,UPPER(DATENAME(DW,[DATE]))AS DAY_NAME
FROM DATESEQUENCE )
,SECOND_FOURTH_SATURDAY AS
(SELECT *
,ROW_NUMBER() OVER (PARTITION BY MONTH_ID ORDER BY DAY_NAME) FALL_IN
FROM DATESATURDAY
WHERE DAY_NAME='SATURDAY')
SELECT * FROM SECOND_FOURTH_SATURDAY
WHERE FALL_IN IN(2,4)
OPTION (MAXRECURSION 10000)
You can get any Saturday of a month using the Following Query in SQL.
Here I'm Getting on Current Date, You can set your own selected date to get a Specific month Saturday
select DATEADD(dd, (14 - ##DATEFIRST - DATEPART(dw, DATEADD(MONTH, DATEDIFF(mm, 0,getdate()), 0))) % 7, DATEADD(MONTH, DATEDIFF(mm, 0, getdate()), 0)) as FirstSaturday,
DATEADD(dd,7,DATEADD(dd, (14 - ##DATEFIRST - DATEPART(dw, DATEADD(MONTH, DATEDIFF(mm, 0, getdate()), 0))) % 7, DATEADD(MONTH, DATEDIFF(mm, 0, getdate()), 0))) as SecondSaturday,
DATEADD(dd,14,DATEADD(dd, (14 - ##DATEFIRST - DATEPART(dw, DATEADD(MONTH, DATEDIFF(mm, 0, getdate()), 0))) % 7, DATEADD(MONTH, DATEDIFF(mm, 0, getdate()), 0))) as ThirdSaturday,
DATEADD(dd,21,DATEADD(dd, (14 - ##DATEFIRST - DATEPART(dw, DATEADD(MONTH, DATEDIFF(mm, 0, getdate()), 0))) % 7, DATEADD(MONTH, DATEDIFF(mm, 0, getdate()), 0))) as LastSaturday

How to use SQL to do a group by with different dates?

Lets say I have a table with the following columns:
Qty, INTEGER
SaleDate, DATETIME
I would now like to see this result:
Sold in the last 7 days | Sold in last 14 days
-----------------------------------------------------
10 | 20
I can use a where clause to use between, however how would I get the qty sold for 7 and 14 days?
Filter in the WHERE clause to get days 0 to -14. Then aggregate on days 0 to -7 separately.
SELECT
...,
SUM(CASE WHEN SaleDate >= DATEADD(day, -7, GETDATE()) THEN 1 ELSE 0 END) AS 7days,
COUNT(*) AS 14days
FROM
MyTable
WHERE
SaleDate >= DATEADD(day, -14, GETDATE())
GROUP BY
...
Tested in MS T-SQL 2003
declare #whatever table(
qty int,
saledate datetime
)
insert into #whatever select 1, getdate()
insert into #whatever select 2, dateadd(dd, -1, getdate())
insert into #whatever select 2, dateadd(dd, -2, getdate())
insert into #whatever select 1, dateadd(dd, -3, getdate())
insert into #whatever select 1, dateadd(dd, -4, getdate())
insert into #whatever select 1, dateadd(dd, -5, getdate())
insert into #whatever select 1, dateadd(dd, -6, getdate())
insert into #whatever select 1, dateadd(dd, -7, getdate())
insert into #whatever select 1, dateadd(dd, -8, getdate())
insert into #whatever select 1, dateadd(dd, -9, getdate())
insert into #whatever select 2, dateadd(dd, -10, getdate())
insert into #whatever select 2, dateadd(dd, -11, getdate())
insert into #whatever select 1, dateadd(dd, -15, getdate())
insert into #whatever select 2, dateadd(dd, -16, getdate())
select
qty,
sum(
case
when datediff(dd, saledate, getdate()) between 0 and 7 then 1
else 0
end
) as [Sold in last 7 days],
sum(
case
when datediff(dd, saledate, getdate()) between 0 and 14 then 1
else 0
end
) as [Sold in last 14 days]
from
#whatever
group by
qty
;
select sum(Qty), datediff(w, getdate(), SaleDate) as Period
from table
group by datediff(ww, getdate(), SaleDate)

Help with a SQL Query

I am wanting to perform a Threshold query, whereby one would take the Value of a field from Today, and compare it to the value from yesterday, this query would look something like this, but obviously, it is wrong, and I can't find how to do it:
select
TableB.Name,
TableA.Charge,
(
select Charge
from TableA
where (DateAdded >= '13/10/2009' and DateAdded < '14/10/2009')
)
from TableA
inner join
TableB on TableB.ID = TableA.ID
where
TableA.DateAdded >= '10/14/2009'
order by
Name asc
Just a quick note, I am looking for two CHARGE fields, not the dates. The date manipulation is simply for Today and Yesterday, nothing more.
At the end of this, I want to do a calculation on the two returned charge fields, so if its easier to show that, that would also be great.
Thanks in advance
Kyle
EDIT1:
The data I am looking for is like so:
Yesterday, we input a charge of 500 to MachineA
Today we input a charge of 300 to MachineA
We run the query, and results I need are as follows:
Name = MachineA
Charge = 300
YesterdayCharge = 500
If you really need previous date (including weekends etc), then following query should do the job. Otherwise please post data samples and expected results:
SELECT TableB.Name,
TableA.Charge,
prev.Charge AS PrevCharge
FROM TableA
INNER JOIN TableB
ON TableA.ID = TableB.ID
LEFT JOIN TableA prev
ON TableA.ID = prev.ID
--// use this if DateAdded contains only date
--AND TableA.DateAdded = DATEADD(day, +1, prev.dateAdded)
--// use this if DateAdded contains also time component
AND CONVERT(DATETIME, CONVERT(CHAR(8), TableA.DateAdded, 112), 112) = DATEADD(day, +1, CONVERT(DATETIME, CONVERT(CHAR(8), prev.dateAdded, 112), 112))
edit-1: added option in JOIN for cases when DateAdded contains time as well
something like this?
SELECT
B.Name,
A.Charge,
DATEPART(day, A.DateAdded) as day
FROM
TableA A, Table B
WHERE
B.ID = A.ID AND
A.DateAdded BETWEEN DATEADD(day, -1, GETDATE()) AND GETDATE()
GROUP BY
B.Name,
A.Charge,
A.DateAdded
Try this:
DECLARE #ValuesTable TABLE(Name VARCHAR(20), Charge INT, DateAdded DATETIME)
INSERT INTO #ValuesTable
SELECT 'Name1', 10, DATEADD(dd, 2, DATEDIFF(dd, 0, GETDATE())) UNION
SELECT 'Name2', 20, DATEADD(dd, 2, DATEDIFF(dd, 0, GETDATE())) UNION
SELECT 'Name1', 30, DATEADD(dd, 1, DATEDIFF(dd, 0, GETDATE())) UNION
SELECT 'Name2', 40, DATEADD(dd, 1, DATEDIFF(dd, 0, GETDATE())) UNION
SELECT 'Name1', 50, DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE())) UNION
SELECT 'Name2', 60, DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE())) UNION
SELECT 'Name1', 70, DATEADD(dd, -1, DATEDIFF(dd, 0, GETDATE())) UNION
SELECT 'Name3', 80, DATEADD(dd, -1, DATEDIFF(dd, 0, GETDATE())) UNION
SELECT 'Name1', 90, DATEADD(dd, -2, DATEDIFF(dd, 0, GETDATE())) UNION
SELECT 'Name2', 100, DATEADD(dd, -2, DATEDIFF(dd, 0, GETDATE()))
SELECT
ISNULL(T.Name,Y.Name) AS Name,
SUM(ISNULL(Y.Charge,0)) AS Yesterday, SUM(ISNULL(T.Charge,0)) AS Today,
SUM(ISNULL(T.Charge,0)) - SUM(ISNULL(Y.Charge,0)) AS Diff
FROM(
SELECT Name, Charge
FROM #ValuesTable
WHERE DateAdded BETWEEN DATEADD(day, -2, GETDATE())
AND DATEADD(day, -1, GETDATE())
) AS Y
FULL JOIN(
SELECT Name, Charge
FROM #ValuesTable
WHERE DateAdded BETWEEN DATEADD(day, -1, GETDATE()) AND GETDATE()
) AS T ON ISNULL(T.Name,Y.Name) = ISNULL(Y.Name,T.Name)
GROUP BY ISNULL(T.Name,Y.Name) , ISNULL(Y.Name,T.Name)
It may be just a typo in SO but if you are using date strings '14/10/2009' and '10/14/2009' in the same query it will never work.
No matter which date format you are using one of them has too many months in it.