Binding parameter in SELECT query for PostgreSQL [duplicate] - sql

This question already has answers here:
How to declare a variable in a PostgreSQL query
(15 answers)
Closed 3 years ago.
select (CURRENT_TIMESTAMP - '60 days'::interval);
This shows me a current time stamp with an interval of 60 days getting subtracted.
SELECT VALUE
FROM schema_name.some_parameter
WHERE some_parameter.NAME LIKE 'some_reference_name'
I want to add the above query in SELECT so that I don't need to add the hardcoded data for 60 days. I want to get it through the parameter variable.
Basically i need to use nested queries where the second query gets me the 60 days value i.e. hardcoded in first query.
Is there a possible solution for my problem?

Maybe something like this?
with v(val)
as
(
VALUES( CURRENT_TIMESTAMP - '60 days'::interval)
)
SELECT v.val from
schema_name.some_parameter cross join v
WHERE some_parameter.NAME LIKE 'some_reference_name'

Related

How to substruct dates in oracle db? [duplicate]

This question already has answers here:
Oracle date difference to get number of years
(5 answers)
Closed 2 years ago.
I want to substruct 2 dates(current date and hairdressing_date) to get the result from table to represent data during last 2 years.
I have following SELECT statement:
SELECT count(c_id)
INTO counter
FROM RESERVATIONS r
WHERE r.customer_id = 1
AND (Sysdate - r.hairdressing_date) / 365 < 2;
It is custom, but I am not sure about '/ 365' part of code.
How to get the needed data correctly?
Could you write the correct implementation of this line?
Please use MONTHS_BETWEEN() function like this:
SELECT MONTHS_BETWEEN(TRUNC(SYSDATE), TO_DATE('22.01.2019', 'DD.MM.YYYY'))/12
FROM DUAL;
and revert to this one considering your case:
SELECT count(c_id)
INTO counter
FROM RESERVATIONS r
WHERE r.customer_id = 1
AND MONTHS_BETWEEN(TRUNC(SYSDATE), hairdressing_date)/12 < 2;

How to fix "Inner Join Group-By" question [duplicate]

This question already has answers here:
ORA-00979 not a group by expression
(10 answers)
Closed 3 years ago.
Trying to run a query to pull back no duplicate lines. Currently when running this script I get an error back from Oracle saying
"ORA-00979: not a GROUP BY expression"
Tried removing different select rows.
SELECT QUEUE_NAME, ITEMS_IN_QUEUE, CREATION_USR_ID
FROM IN_WF_QUEUE B
INNER JOIN IN_WF_ITEM A
ON A.QUEUE_ID = B.QUEUE_ID
AND B.QUEUE_NAME LIKE '__________ %'
AND (A.QUEUE_START_TIME < (select sysdate from DUAL)-1000)
GROUP BY B.QUEUE_ID;
Thank you in advance for any help on this issue.
If you want to remove duplicates, why don't you use DISTINCT? That's more natural than using GROUP BY without any aggregates.
SELECT DISTINCT
queue_name, items_in_queue, creation_usr_id
FROM in_wf_queue b
INNER JOIN in_wf_item A
ON A.queue_id = b.queue_id
AND b.queue_name LIKE '__________ %'
AND A.queue_start_time < sysdate - 1000;
Also, there's no need to select SYSDATE from dual; it is a function that can be used standalone, as in my example. Note that it returns both date and time, so - maybe you'd want to remove time component by truncating it, i.e. use trunc(sysdate). Subtracting 1000 from it means "1000 days ago"; just saying, to avoid possible confusion.

Oddities with postgres SQL [negative date interval and alias that doesn't work only in condition clause]

I'm coming to you guys with with two small oddities I can't seem to understand with postgres:
(1)
SELECT "LASTREQUESTED",
(DATE_TRUNC('seconds', CURRENT_TIMESTAMP - "LASTREQUESTED")
- INTERVAL '8 hours') AS "TIME"
FROM "USER" AS u
JOIN "REQUESTLOG" AS r ON u."ID" = r."ID"
ORDER BY "TIME"
I'm calculating when users can make their next request [once every 8 hours], but if you look at entry 16 I get "1 day -06:20:47" instead of "18:00:00" ish, unlike every other line. [The table LASTREQUESTED is a simple timestamp, nothing different here from the other entries for line 16], why is that?
(2)
On the same request, if I try to add a condition on the "TIME" column, the compiler says it doesn't exist although using it to order by is ok. I don't get why.
SELECT (DATE_TRUNC('seconds', CURRENT_TIMESTAMP - "LASTREQUESTED")
- INTERVAL '8 hours') AS "TIME"
FROM "USER" AS u
JOIN "REQUESTLOG" AS r ON u."ID" = r."ID"
WHERE "TIME" > 0
ORDER BY "TIME";
Question #1: negative hours but positive days?
According to the PostgreSQL documentation, this is a situation where PostgreSQL differs from the SQL standard:
According to the SQL standard all fields of an interval value must have the same sign…. PostgreSQL allows the fields to have different signs….
Internally interval values are stored as months, days, and seconds. This is done because the number of days in a month varies, and a day can have 23 or 25 hours if a daylight savings time adjustment is involved. The months and days fields are integers while the seconds field can store fractions. …
You can see a more extreme example of this with the following query:
=# select interval '1 day' - interval '300 hours';
?column?
------------------
1 day -300:00:00
(1 row)
So this is not a single interval in seconds expressed in a strange way; instead, it's an interval of 0 months, +1 day, and -1,080,000.0 seconds. If you are certain that there's no daylight savings time issues with the timestamps that you got these intervals from, you can use justify_hours to convert days into 24-hour periods and get an interval that makes more sense:
=# select justify_hours(interval '1 day' - interval '300 hours');
justify_hours
--------------------
-11 days -12:00:00
Question #2: SELECT columns can't be used in WHERE?
This is standard PostgreSQL behavior. See this duplicate question. Solutions presented there include:
Repeat the expression twice, once in the SELECT list, and again in the WHERE clause. (I've done this more times than I want to remember…)
SELECT (my - big * expression) AS x
FROM stuff
WHERE (my - big * expression) > 5
ORDER BY x
Create a subquery without that WHERE filter, and put the WHERE conditions in the outer query
SELECT *
FROM (SELECT (my - big * expression) AS x
FROM stuff) AS subquery
WHERE x > 5
ORDER BY x
Use a WITH statement to achieve something similar to the subquery trick.
I don't now exactly why it's calculating as-is (maybe because you subtract an Interval from another Interval) but when you change the calculation to Timestamp minus Timestamp it works as expected:
DATE_TRUNC('seconds', CURRENT_TIMESTAMP - (LASTREQUESTED + INTERVAL '8 hours'))
See Fiddle
Regarding #2: Based on Standard SQL the columns in the Select-list are calculated after FROM/WHERE/GROUP BY/HAVING, but before ORDER, that's why you can't use an alias in WHERE. There are some good articles on that topic written by Itzik Ben-Gan (based on MS SQL Server, but similar for PostgreSQL).

can you get me select statement Modified_Date=Today? [duplicate]

This question already has answers here:
how to get current/Todays date data in sql server
(5 answers)
Closed 4 years ago.
I need to get all the records using MS SQL SELECT where Modified_Date=Today
my table looks like:
created_by modified_date
20150723081006 2015-07-23 15:14:22.843
20150723081006 2015-09-04 00:14:24.463
20150723081006 2015-09-04 00:14:24.463
One simple way to accomplish this would be to cast your modified date as a date value (removing the time portion) and then comparing it to the current date (again, with time removed):
SELECT *
FROM MyTable
WHERE CAST(Modified_Date AS DATE) = CAST(GETDATE() AS DATE)

Selecting records based on other records using separate date/time fields [duplicate]

This question already has answers here:
TSQL to combine a date field and a time field
(4 answers)
Closed 9 years ago.
I have a database that stores date and time in separate fields. I need to select all records that occurred within + and - 90 minutes of the date and time each of these happened.
I am able to get everything in the format I need to pull it off
SELECT UFV1.USR_DATE
,UFV1.USR_TIME
,LEFT(CAST(DATEADD(minute, -90, UFV1.USR_TIME) AS TIME),8) AS MIN_TIME
,LEFT(CAST(DATEADD(minute, +90, UFV1.USR_TIME) AS TIME),8)AS MAX_TIME
FROM USR_Y_FACILITY_VISIT UFV1
WHERE UFV1.MASTER_CUSTOMER_ID = '2'
ORDER BY UFV1.USR_DATE, UFV1.USR_TIME
Where I am stuck is I need to build a query that takes this info (basically the min/max from each line) then selects all the info in the same table based off that. Thank you for your help I am totally stumped as to where to go next.
Add the key fields for the table to your query as given, along with a corresponding GROUP BY clause. Then query your data table joind to that query as a sun-query on this format:
SELECT *
FROM T
JOIN ( SELECT * ... ) U
ON U.key = T.key
AND T.dateTime BETWEENU.MinDateTime AND U.MaxDateTime
If I correctly understood a question then, this request is necessary for you
SELECT *
FROM USR_Y_FACILITY_VISIT UFV1
WHERE EXISTS (
SELECT 1
FROM USR_Y_FACILITY_VISIT UFV2
WHERE UFV2.MASTER_CUSTOMER_ID = '2'
AND UFV1.USR_DATE = UFV2.USR_DATE
AND UFV1.USR_TIME BETWEEN CAST(DATEADD(minute, -90, UFV2.USR_TIME) AS time)
AND CAST(DATEADD(minute, 90, UFV2.USR_TIME) AS time)
)