I have a table named nifty_50 with the below two columns.
Date Close
Apr 07, 2022 17,763.40
Apr 06, 2022 17,807.65
Apr 05, 2022 17,957.40
Apr 04, 2022 18,053.40
Apr 01, 2022 17,670.45
Mar 31, 2022 17,464.75
I am trying to add another column which says the day name of the Date column.
Expected Output:
Date Close Day_name
Apr 07, 2022 17,763.40 Thursday
Apr 06, 2022 17,807.65 Wednesday
Apr 05, 2022 17,957.40 Tuesday
Apr 04, 2022 18,053.40 Monday
Apr 01, 2022 17,670.45 Friday
Mar 31, 2022 17,464.75 Thursday
I tried doing
select date, close, datename(date ,getdate()) as day_name, from nifty_50;
The above code doesn't work and all the other codes which i googled and tried also don't work. I know this is a simple code. can someone please help me with this?
Use the TO_CHAR function with the Day format model.
select "DATE",
close,
TO_CHAR("DATE", 'fmDay') as day_name
from nifty_50;
Note: fmDay will strip trailing spaces from the day names (otherwise the days will all be output as strings of length equal to the longest day name padded with trailing spaces).
Note 2: DATE is a reserved word in Oracle and cannot be used as an unquoted identifier. It is better practice to pick a different identifier instead of using reserved words.
Which, for the sample data:
CREATE TABLE nifty_50 ("DATE", Close) AS
SELECT DATE '2022-04-07', 17763.40 FROM DUAL UNION ALL
SELECT DATE '2022-04-06', 17807.65 FROM DUAL UNION ALL
SELECT DATE '2022-04-05', 17957.40 FROM DUAL UNION ALL
SELECT DATE '2022-04-04', 18053.40 FROM DUAL UNION ALL
SELECT DATE '2022-04-01', 17670.45 FROM DUAL UNION ALL
SELECT DATE '2022-03-31', 17464.75 FROM DUAL;
Outputs:
DATE
CLOSE
DAY_NAME
2022-04-07 00:00:00
17763.4
Thursday
2022-04-06 00:00:00
17807.65
Wednesday
2022-04-05 00:00:00
17957.4
Tuesday
2022-04-04 00:00:00
18053.4
Monday
2022-04-01 00:00:00
17670.45
Friday
2022-03-31 00:00:00
17464.75
Thursday
db<>fiddle here
You can try below to fetch Day name:
DECLARE #DateVal DATE = '2022-07-04';
SELECT #DateVal As [Date],
DATENAME(WEEKDAY, #DateVal) AS [Day Name],
DATENAME(DW, #DateVal) AS [Day Name],
DATENAME(W, #DateVal) AS [Day Name];
Related
I have a table that has DATE_VALUE, FISCAL_WEEK, FISCAL_YEAR
DATE_VALUE FISCAL_WEEK FISCAL_YEAR
24-DEC-21 52 2021
25-DEC-21 52 2021
26-DEC-21 52 2021
27-DEC-21 53 2021
28-DEC-21 53 2021
29-DEC-21 53 2021
30-DEC-21 53 2021
31-DEC-21 53 2021
01-JAN-22 53 2021
02-JAN-22 53 2021
03-JAN-22 1 2022
04-JAN-22 1 2022
05-JAN-22 1 2022
06-JAN-22 1 2022
07-JAN-22 1 2022
08-JAN-22 1 2022
09-JAN-22 1 2022
10-JAN-22 2 2022
11-JAN-22 2 2022
12-JAN-22 2 2022
13-JAN-22 2 2022
14-JAN-22 2 2022
The table goes on for the entire FY 2021 & 2022
I want to get the last 4 fiscal weeks (FW) prior to the current week. Let's assume this week is FW20 FY2022, I am able to get this result:
FISCAL_WEEK FISCAL_YEAR
16 2022
17 2022
18 2022
19 2022
The code used to return the above output is:
SELECT
*
FROM
(
WITH t AS (
SELECT
fiscal_week - 1 lastweek,
fiscal_week - 5 week_x,
fiscal_year
FROM
TABLE
WHERE
Trunc(date_value) = Trunc(sysdate)
)
SELECT
DISTINCT fiscal_week,
t.fiscal_year
FROM
TABLE
OUTER JOIN t ON fiscal_week <> week_x
WHERE
to_char(fiscal_week) BETWEEN lastweek - 4
AND lastweek
ORDER BY
fiscal_week
)
But if the current week was FW04 FY2022, the code above is not able to return this desired output.
FISCAL_WEEK FISCAL_YEAR
53 2021
1 2022
2 2022
3 2022
Similarly, if the current was FY03 FY2022, I want the output to be:
FISCAL_WEEK FISCAL_YEAR
52 2021
53 2021
1 2022
2 2022
How do I need to write the code to get this output? Maybe the case statement could work but I'd like to see if there's any other workaround? Any help would be appreciated.
Thank you!
You may put the condition on the date value not the week to get the required output, then use OFFSET 1 to skip the current week and fetch the next 4 rows only. Try the following:
WITH T AS
(
SELECT DISTINCT fiscal_week, fiscal_year
FROM TABLE_NAME
WHERE Trunc(date_value) <= Trunc(SYSDATE)
ORDER BY fiscal_year DESC, fiscal_week DESC
OFFSET 1 ROWS
FETCH NEXT 4 ROWS ONLY
)
SELECT fiscal_week, fiscal_year
FROM T ORDER BY fiscal_year, fiscal_week
See a demo.
Don't use the FISCAL_WEEK and FISCAL_YEAR columns; just use the DATE column and compare it to a range based on the start of the ISO week:
SELECT DISTINCT fiscal_week, fiscal_year
FROM table_name
WHERE "DATE" < TRUNC(SYSDATE, 'IW')
AND "DATE" >= TRUNC(SYSDATE, 'IW') - INTERVAL '28' DAY
ORDER BY fiscal_year, fiscal_week;
Which, for the sample data:
Create Table table_name("DATE", FISCAL_WEEK, FISCAL_YEAR) AS
SELECT DATE '2021-12-24', 52, 2021 FROM DUAL UNION ALL
SELECT DATE '2021-12-25', 52, 2021 FROM DUAL UNION ALL
SELECT DATE '2021-12-26', 52, 2021 FROM DUAL UNION ALL
SELECT DATE '2021-12-27', 53, 2021 FROM DUAL UNION ALL
SELECT DATE '2021-12-28', 53, 2021 FROM DUAL UNION ALL
SELECT DATE '2021-12-29', 53, 2021 FROM DUAL UNION ALL
SELECT DATE '2021-12-30', 53, 2021 FROM DUAL UNION ALL
SELECT DATE '2021-12-31', 53, 2021 FROM DUAL UNION ALL
SELECT DATE '2022-01-01', 53, 2021 FROM DUAL UNION ALL
SELECT DATE '2022-01-02', 53, 2021 FROM DUAL UNION ALL
SELECT DATE '2022-01-03', 1, 2022 FROM DUAL UNION ALL
SELECT DATE '2022-01-04', 1, 2022 FROM DUAL UNION ALL
SELECT DATE '2022-01-05', 1, 2022 FROM DUAL UNION ALL
SELECT DATE '2022-01-06', 1, 2022 FROM DUAL UNION ALL
SELECT DATE '2022-01-07', 1, 2022 FROM DUAL UNION ALL
SELECT DATE '2022-01-08', 1, 2022 FROM DUAL UNION ALL
SELECT DATE '2022-01-09', 1, 2022 FROM DUAL UNION ALL
SELECT DATE '2022-01-10', 2, 2022 FROM DUAL UNION ALL
SELECT DATE '2022-01-11', 2, 2022 FROM DUAL UNION ALL
SELECT DATE '2022-01-12', 2, 2022 FROM DUAL UNION ALL
SELECT DATE '2022-01-13', 2, 2022 FROM DUAL UNION ALL
SELECT DATE '2022-01-14', 2, 2022 FROM DUAL UNION ALL
SELECT DATE '2022-02-14', 6, 2022 FROM DUAL;
If SYSDATE was 2022-01-17, would output:
FISCAL_WEEK
FISCAL_YEAR
52
2021
53
2021
1
2022
2
2022
fiddle
I want to create a date column which would take 'year' and 'month' and give me a date starts from 1st
E_name s_date year month
a 01-08-2012 2012 MAR
a 23-06-2012 2010 DEC
a 19-03-2020 2020 DEC
a 14-02-2020 2020 MAR
b 27-12-2018 2018 DEC
REQUIRED OUTPUT
E_name s_date year month Date
a 01-08-2012 2012 MAR 01-03-2012
a 23-06-2012 2010 DEC 01-12-2010
a 19-03-2020 2020 DEC 01-12-2020
a 14-02-2020 2020 MAR 01-03-2020
b 27-12-2018 2018 DEC 01-12-2018
Concatenate the year and month columns and then use TO_DATE:
SELECT t.*,
TO_DATE(month || year, 'MONYYYY', 'NLS_DATE_LANGUAGE=American') AS "Date"
FROM table_name t
Which, for your sample data:
CREATE TABLE table_name (E_name, s_date, year, month) AS
SELECT 'a', DATE '2012-08-01', 2012, 'MAR' FROM DUAL UNION ALL
SELECT 'a', DATE '2012-06-23', 2010, 'DEC' FROM DUAL UNION ALL
SELECT 'a', DATE '2020-03-19', 2020, 'DEC' FROM DUAL UNION ALL
SELECT 'a', DATE '2020-02-14', 2020, 'MAR' FROM DUAL UNION ALL
SELECT 'b', DATE '2018-12-27', 2018, 'DEC' FROM DUAL;
Outputs:
E_NAME
S_DATE
YEAR
MONTH
Date
a
01-08-2012
2012
MAR
01-03-2012
a
23-06-2012
2010
DEC
01-12-2010
a
19-03-2020
2020
DEC
01-12-2020
a
14-02-2020
2020
MAR
01-03-2020
b
27-12-2018
2018
DEC
01-12-2018
db<>fiddle here
I have two tables: 'project' and 'project_status' in a BigQuery database...
project
Id Name
1 XXXX
2 YYYY
3 ZZZZ
project_status
project_id status_date status
1 2 Jan 2020 Good
2 4 Feb 2020 Bad
3 5 Feb 2020 On track
3 6 March 2020 Bad
I want to produce a monthly report of project status. The status of a project is not updated each month. In this case the most recent status entry up to the month end is taken as the latest status
Month Project Status
Jan 2020 XXXX Good
Feb 2020 XXXX Good
Mar 2020 XXXX Good
Jan 2020 YYYY null
Feb 2020 YYYY Bad
Mar 2020 YYYY Bad
Jan 2020 ZZZZ null
Feb 2020 ZZZZ On track
Mar 2020 ZZZZ Bad
For example, with project 'XXXX', there is no status update for Feb 2020 or March 2020, so the status is to be taken from the most recent status entry of 2 Jan 2020.
Any suggestions on how to build a SQL query to deliver this report?
Consider using GENERATE_DATE_ARRAY AND ARRAY_AGG:
WITH Months AS (
SELECT DATE_SUB(month, INTERVAL 1 DAY) AS last_day
FROM UNNEST(GENERATE_DATE_ARRAY('2020-02-01', '2020-04-02', INTERVAL 1 MONTH)) AS month
),
Projects as (
SELECT 1 AS Id, 'XXXX' AS Name UNION ALL
SELECT 2 AS Id, 'YYYY' AS Name UNION ALL
SELECT 3 AS Id, 'ZZZZ' AS Name
),
Project_Status as (
SELECT 1 AS project_id, PARSE_DATE('%e %b %Y', '2 Jan 2020') AS status_date, 'Good' AS status UNION ALL
SELECT 2, PARSE_DATE('%e %b %Y', '4 Feb 2020'), 'Bad' UNION ALL
SELECT 3, PARSE_DATE('%e %b %Y', '5 Feb 2020'), 'On track' UNION ALL
SELECT 3, PARSE_DATE('%e %b %Y', '6 March 2020'), 'Bad'
)
SELECT Projects.Name as Name, DATE_TRUNC(Months.last_day, MONTH) AS Month,
ARRAY_AGG(Project_Status.status ORDER BY status_date DESC)[OFFSET(0)] AS Status
FROM Projects
CROSS JOIN Months
LEFT JOIN Project_Status ON
Project_Status.project_id = Projects.id
AND Project_Status.status_date <= Months.last_day
GROUP BY Name, Month
The output is:
I'm attempting to convert a string to a timestamp within Bigquery. The question is really simple, how do I convert this string Jan 30 2016 12:00AM or Aug 9 2015 12:00AM to date?
I have tried referring to the Bigquery documentation but it didn't seem to work:
(https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#parse_date)
select PARSE_DATE('%b %e %E4Y', 'Jan 30 2016 12:00AM')
select PARSE_DATE('%b %e %E4Y', 'Aug 9 2015 12:00AM')
Your input string is actually a timestamp, not a date, because it has a time component at the end. So, consider using PARSE_TIMESTAMP instead:
SELECT PARSE_TIMESTAMP('%b %e %E4Y %I:%M%p', 'Jan 30 2016 12:00AM') AS ts_out
FROM yourTable;
This would return a timestamp based on the input string. If you really want a date, you could cast the above to date, or you could just use LEFT on the string input to restrict to only the date portion:
SELECT PARSE_DATE('%b %e %E4Y', LEFT('Jan 30 2016 12:00AM', 11)) AS ts_out
FROM yourTable;
Below is for BigQuery Standard SQL
SELECT DATE(PARSE_TIMESTAMP('%b %e %Y %R%p', ts))
You can test it with dummy data as in below example
#standardSQL
WITH `project.dataset.table` AS (
SELECT 'Jan 30 2016 12:00AM' ts UNION ALL
SELECT 'Aug 9 2015 12:00AM' UNION ALL
SELECT 'Aug 9 2015 12:00AM'
)
SELECT ts, DATE(PARSE_TIMESTAMP('%b %e %Y %R%p', ts)) date_from_ts
FROM `project.dataset.table`
with result
Row ts date_from_ts
1 Jan 30 2016 12:00AM 2016-01-30
2 Aug 9 2015 12:00AM 2015-08-09
3 Aug 9 2015 12:00AM 2015-08-09
This query counts the amount of bottles we produce over a month and groups them by day. If there are no bottles produces that day then it is skipped from the output instead of returning 0 bottles produced. How can I return with the day's timestamp if there are no bottles produced? I heard the calendar table has to be used for this.
SELECT CONVERT(datetime,CAST(t_stamp AS DATE)), COUNT(bottles) AS 'Good Bottles'
FROM bottles
WHERE t_stamp
BETWEEN "any date"
AND "any date"
GROUP BY CAST(t_stamp AS DATE)
ORDER BY CAST(t_stamp AS DATE) ASC
Current Output:
Aug 12, 2019 12:00 am..................4302
Aug 13, 2019 12:00 am..................2302
Aug 17, 2019 12:00 am..................1302
Aug 18, 2019 12:00 am..................4302
Desired Output:
Aug 12, 2019 12:00 am..................4302
Aug 13, 2019 12:00 am..................2302
Aug 14, 2019 12:00 am..................0
Aug 15, 2019 12:00 am..................0
Aug 16, 2019 12:00 am..................0
Aug 17, 2019 12:00 am..................1302
Aug 18, 2019 12:00 am..................4302
You need to generate the days. A pretty simple method uses a recursive CTE:
WITH dates as (
SELECT CONVERT(date, "any date1") as dte
UNION ALL
SELECT DATEADD(day, 1, dte)
FROM dates
WHERE dte < "any date2"
)
SELECT d.dte, COUNT(bottles) AS GoodBottles
FROM dates d LEFT JOIN
bottles b
ON CAST(t_stamp as DATE) = d.dte
GROUP BY d.dte
ORDER BY d.dte ASC;
Notes:
If you have a calendar or tally table, then use that instead.
If the number of dates exceed 100, you need to add OPTION (MAXRECURSION 0).
COUNT(bottles) looks suspicious. Do you really intend SUM(bottles)?
Converting a column to a date and then to a datetime is also suspicious. It is unclear why you would want a datetime for the first column.