PostgreSQL LIKE query - sql

I want to get sales with date, which started with'2007-02':
SELECT *
FROM payment
WHERE payment_date LIKE '2007%';
But there is the error:
ERROR: ERROR: operator does not exist: timestamp without time zone ~~ unknown
LINE 9: WHERE payment_date LIKE '2007%'
^
HINT: Operator with given name and argument types could not be found. Perhaps you should add explicit casts.
But another query as
SELECT email
FROM customer
WHERE first_name = 'Kelly'
AND last_name LIKE 'K%';
work proper. How can i force this query to work?
You can get my learning database via link: https://dropmefiles.com/LX8cu

I want to get sales with date, which started with '2007-02':
LIKE is a string function. As the error message indicates, the payment_date column is of timestamp datatype, so use date filtering:
where payment_date >= date '2007-02-01' and payment_date < date '2017-03-01'
Or, if you want the whole year:
where payment_date >= date '2007-01-01' and payment_date < date '2018-01-01'
You might be tempted to use a date function to extract the year part of the date, and use it for comparison:
where extract(year from payment_date) = 2007
I would not recommend that; this is far less efficient, because the function needs to be applied to the entire column before the filtering can happen, as opposed to the direct filtering against literals. One says that the expression is not SARGable.

The error message really says it all - the like operator takes strings on both its sides, while you have a timestamp.
An alternative approach could be to extract the year:
SELECT *
FROM payment
WHERE EXTRACT(YEAR FROM payment_date) = 2007;

I assume that your fiel payment_date is of type date, time or timestamp.
Try to convert the date/time into string before using the like operator.
https://www.postgresql.org/docs/13/functions-formatting.html

Related

DATEDIFF - What is wrong with my SQL query?

I have the table ORDERS and while trying to find the processing time for each order by subtracting the date of receipt from the date of delivery, I keep getting this error:
SQL0206N "DAY" is not valid in the context where it is used.
SQLSTATE=42703
My query is the following:
SELECT DATEDIFF(DAY, ReceiptDate, DeliveryDate) FROM ORDERS
I suspect it has something to do with the date's format in the columns ReceiptDate and DeliveryDate: DD/MM/YY. Does this have to be converted? What am I doing wrong?
EDIT: Is there an alternative for using DATEDIFF? Can I convert each individual date to an int of days and then subtract the two ints?
If you are using DB2, then there is no DATEDIFF function, which is specific to SQL Server. However, we can easily simulate it by taking a difference of days, using the DAYS() function:
SELECT DAYS(DeliveryDate) - DAYS(ReceiptDate) AS days_diff
FROM ORDERS;

Date invalid when no match is found in DB2

I'm running a very simple DB2 query which is giving me a timestamp error because it can't find records with 2019-02-29 and so it's returning an invalid date type. If I change it to 2019-02-28 then it works.
I can't seem to find a proper "CASE WHEN" use for this, but is there a simple way to not interfere with current functionality but to say "If this date isn't found just ignore today's date"?
I need it to run even if there are nor prior year records for 02-29
SELECT 'DATE' AS RANGE, COUNT(*) AS COUNT
FROM datesTable
WHERE user = 123
AND newDate BETWEEN '2019-01-01' AND '2019-02-29'
I think a case should work:
newDate BETWEEN '2019-01-01' AND
(CASE WHEN '2019-02-29' <> '2019-02-29' THEN '2019-02-29' END)
This assumes that you are constructing the value somehow, based on the current date.
The problem is because the column is a date so the operands to BETWEEN are all converted to dates. The case comparison should get around this, by only converting when the data is not the forbidden date.
Or, do the comparisons as strings:
where varchar_format(newDate, 'YYYY-MM-DD') between '2019-01-01' AND '2019-02-29'
No conversion to date is happening here, so no error should occur. That said, this will prevent the use of an index on newDate.

How to use PostgreSQL to calculate the completion time of two timestamp records?

I have an invitations table with the following fields:
Invitations: id, created_at, completed_at
I am working to write a PostgreSQL query that breaks down the data by weekly cohorts (last 7 days) and show the average completion time (the difference between created_at and completed_at in days). FYI, it's possible for completed_at to be null, meaning not completed.
Here is what I have so far:
SELECT TRUNC(DATE_PART('day', CURRENT_DATE - i.created_at )/7) AS weeks_ago,
date(min(i.created_at)) AS "Date Start",
date(max(i.created_at)) AS "Date End",
count(DISTINCT i.id) AS "Total Num Invites",
TIMESTAMPDIFF('day', i.created_at, i.completed_at)
FROM invitations i
GROUP BY weeks_ago
ORDER BY weeks_ago ASC;
This is erroring with:
ERROR: function timestampdiff(unknown, timestamp without time zone, timestamp without time zone) does not exist
LINE 5: TIMESTAMPDIFF('day', i.created_at, i.completed_at)
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
, Time: 0.085000s
I'm using PostgreSQL, what am I doing wrong here?
TIMESTAMPDIFF is not natural of PostgreSQL. See here: Postgresql date/time functions.
In PostgreSQL, date operations are like number operations.
Example:
SELECT '2020-01-05 00:01:05'::timestamp - '2020-01-02 00:05:05'::timestamp
-- you get: 2 days 23:56:00
So, to simulate TIMESTAMPDIFF(SQL_TSI_DAY, i.created_at, i.completed_at) you have to do:
DATE_PART('day', i.completed_at - i.created_at)
Wiht the previous example you have:
SELECT DATE_PART('day', '2020-01-05 00:01:05'::timestamp-'2020-01-02 00:05:05'::timestamp)
-- you get: 2
Your biggest hint is ERROR: function timestampdiff(unknown,. This is telling you that it does not know what datatype the value you are giving the function is. TIMESTAMPDIFF() requires the first parameter to be one of a defined list of constants. In your case SQL_TSI_DAY, like:
TIMESTAMPDIFF(SQL_TSI_DAY, i.created_at, i.completed_at)
This link might be helpful. It gives some details on the TIMESTAMPDIFF() function.
EDIT: Replaced the link above. The first link I posted had some typos and incorrect data.

Oracle query BETWEEN (date) AND (date)

My table "Message" contain a column name : message_date (datatype : TIMESTAMP) which stores date and time. But in this case, I would like to only show the date of the data, so I use the method to_char(case(message_date as date),'DD-MM-YYYY')
SELECT msg_id, msg_details, to_char(cast(message_date as date) ,'DD-MM-YYYY')as "DATE"
FROM message
WHERE message LIKE '%hi%'
AND to_char(cast(message_date as date), 'DD-MM-YYYY')
BETWEEN '15-01-2018'
AND '30-01-2018'
I would like to show only the row between the date 15-01-2018 and 30-01-2018. But in the end, the query result came out with the data which from date 15 - 30..where row with other month (exp: 20-03-2018 also shown in the result. I not sure why it only check for the date and not together with month and year...
Seek for help ..thanks
Use date literals with the dates in an ISO compliant format:
WHERE
message LIKE '%hi%' AND
message_date BETWEEN date '2018-01-15' AND date '2018-01-30'
Notr that you don't need to cast message_date to text, because it is already a timestamp and can be directly compared to dates.
The only issue with using BETWEEN when comparing dates is if one or more of the dates you're comparing has a time portion. For example, the date 30-JAN-18 01.32.32 PM certainly isn't between 15-JAN-18 and 30-JAN-18 - it's greater (er, later) than the latter date. Plus while using BETWEEN, which is inclusive, there is always the chance of including an edge case you didn't intend. My recommendation would be to do something like this:
SELECT msg_id, msg_details, TO_CHAR(message_date, 'DD-MM-YYYY') AS "DATE"
FROM message
WHERE message LIKE '%hi%'
AND message_date >= DATE'2018-01-15'
AND message_date < DATE'2018-01-30' + 1;
Notice in the first line I got rid of your CAST() - there is no reason to cast a date value to the DATE datatype. In the last line I'm using a bit of Oracle date arithmetic; this will give me all dates up to and including 30-JAN-18 11:59.59.9999.....
As an aside you might want to apply the LOWER() function to message in your WHERE clause:
WHERE LOWER(message) LIKE '%hi%'
otherwise you will miss messages containing Hi, HI, hI, etc.

Find record between two dates

When I write below query it gives record .
SELECT [srno],[order_no],[order_date],[supplier_name],[item_code],[item_name],[quntity]
FROM [first].[dbo].[Purchase_Order]
WHERE order_date BETWEEN '22/04/2015' AND '4/05/2015'
In this query if I don't add 0 in '4/05/2015' it returns record.
But when I add 0 to the date i.e. '04/05/2015' it doesn't give any records.
SELECT [srno],[order_no],[order_date],[supplier_name],[item_code],[item_name],[quntity]
FROM [first].[dbo].[Purchase_Order]
WHERE order_date BETWEEN '22/04/2015' AND '04/05/2015'
The reason it's not working because SQL is trying to do a string comparison because both your types are string types, But what you really want to do a date comparison.
You should do something like this. Since you only need date part you can strip off the time and use style 103 for your format dd/mm/yyyy.
WHERE CONVERT(DATETIME,LEFT(order_date,10),103)
BETWEEN CONVERT(DATETIME,'20150422') AND CONVERT(DATETIME,'20150504')
Alternately you can use this as well if your order_date has dates like this 5/4/2015 03:20:24PM
WHERE CONVERT(DATETIME,LEFT(order_Date,CHARINDEX(' ', order_Date) - 1),103)
BETWEEN CONVERT(DATETIME,'20150422') AND CONVERT(DATETIME,'20150504')
A long term solution is to change your column order_date to DATE/DATETIME
It Better to Cast it to date rather than depend on IMPLICIT conversion
SELECT [srno],[order_no],[order_date],[supplier_name],[item_code],
[item_name],[quntity] FROM [first].[dbo].[Purchase_Order] where
convert(date,order_date,105) BETWEEN cast('22/04/2015' as Date) AND cast('04/05/2015' as date)