SQL: Verify if date is between two dates - sql

How can i check if an date value equals a date within the summer period.
I'd expect it to be something like:
SELECT Row WHERE Orderdate BETWEEN '01/01/%' AND '31/08/%'
However i'm not allowed to use wildcards in a BETWEEN Clause, right?
/edit
That works, thanks both u guys! i'm sorry i can only pick one correct answer.

i'm not allowed to use wildcards in a BETWEEN, right?
No but you could do this:
SELECT Row WHERE MONTH(Orderdate) BETWEEN 1 AND 8
Note that adding an index on MONTH(Orderdate) will significantly speed up this query since otherwise it will have to do an INDEX SCAN or TABLE SCAN.

You want the "summer" (undefined) period. Most SQL databases would allow you to do:
WHERE month(Orderdate) in (6, 7, 8)
Otherwise, you can use extract(month from OrderDate) in (6, 7, 8)).
This assumes that the month period is defined as June, July, and August. And, there are many other database-specific solutions.

Related

using where clause in SQL

I'm using postgre sql and I have a problem with where clause.
What I wanted to do was:
compare each month's data to that of previous month
select location where august to july ratio was lower than 0.7
Below is my code. I used cast as decimal because without that the result was just integers (either 0 or 1).
If I run the query, it does not return any results. It doesn't say error, but that there is no data where august < 0.7 (But there is! I checked in the original table without the where clause)
SELECT location
, round(cast(june as decimal)/may, 3) as june
, round(cast(july as decimal)/june, 3) as july
, round(cast(august as decimal)/july, 3) as august
FROM per_country
WHERE august < 0.7
Can you tell me what is wrong with my code? Thank you in advance
You cannot reuse an alias defined in the select clause in the where clause. You need to repeat the expression, or use a derived table (subquery, cte):
SELECT location
, round(june::numeric/may, 3) as june
, round(july::numeric/june, 3) as july
, round(august::numeric/july, 3) as august
FROM per_country
WHERE august::numeric/july < 0.7
Note that your existing query indicates of a bad design. You should not be storing each month in a separate table, for many reasons (scalability, efficiency, maintainability, ...). Instead, you should have each month on a separate row.

Why is the result of datediff year in Firebird too high?

I have question about function datediff in firebird. When I try to diff two dates like 15.12.1999 and 30.06.2000 in sql like this
SELECT
SUM(datediff (YEAR, W.FROM, W.TO)),
SUM(datediff (MONTH, W.FROM, W.TO)),
SUM(datediff (DAY, W.FROM, W.TO))
FROM WORKERS W
WHEN W.ID=1
I get in result 1 year, 6 month and 198 days but it is not true with value years (of course result should be 0) How I have to write my query to get correct result in parameter year? In that link https://firebirdsql.org/refdocs/langrefupd21-intfunc-datediff.html in documentation there is information about this case but there is not how to solve this problem.
The documentation is not very clear, but I'm pretty sure that datediff() is counting the number of boundaries between two dates. (This is how the very similar function in SQL Server works.) Hence, for year, it is counting the number of "Dec 31st/Jan 1st" boundaries. This is explicitly explained in the documentation.
If you want a more accurate count, you can use a smaller increment. The following is pretty close:
(datediff(day, w.from, t.to) / 365.25) as years_diff

Querying SQLITE DB for Data from One Column Based On Another Column

I hope the title of this post makes sense.
The db in question has two columns that are related to my issue, a date column that follows the format xx/xx/xxxx and price a column. What I want to do is get a sum of the prices in the price column based on the month and year in which they occurred, but that data is in the other aforementioned column. Doing so will allow me to determine the total for a given month of a given year. The problem is I have no idea how to construct a query that would do what I need. I have done some reading on the web, but I'm not really sure how to go about this. Can anyone provide some advice/tips?
Thanks for your time!
Mike
I was able to find a solution using a LIKE clause:
SELECT sum(price) FROM purchases WHERE date LIKE '11%1234%'
The "11" could be any 2-digit month and the "1234" is any 4 digit year. The % sign acts as a wildcard. This query, for example, returns the sum of any prices that were from month 11 of year 1234 in the db.
Thanks for your input!
You cannot use the built-in date functions on these date values because you have stored them formatted for displaing instead of in one of the supported date formats.
If the month and day fields always have two digits, you can use substr:
SELECT substr(MyDate, 7, 4) AS Year,
substr(MyDate, 1, 2) AS Month,
sum(Price)
FROM Purchases
GROUP BY Year,
Month
So, the goal is to get an aggregate grouping by the month?
select strftime('%m', mydate), sum(price)
from mytable
group by strftime('%m', mydate)
Look into group by

How to break down smalldatetime into year, month, day indexes?

I am using SQL Server 2008.
I have some dates in my database that I "think" I want to break down into smaller parts. The dates are birthdays and death days. I want to be able to output them like by querying people who were born in October or on May 12th or in 1945.
I was told that a typical way of doing this is to take a date and break it into smaller pieces and put each piece of the date into its own column, like this:
2001-03-12 00:00:00 // EventDate column
Add these columns:
2001 // EventYear column
03 // EventMonth column
12 // EventDay column
First, is this a good way of doing this? If so, second, can I somehow have SQL Server automatically break the date part and put it into its own columns?
I'd appreciate ideas and solutions.
I would recommend that you leave it as a date column and then use DatePart in queries to filter results.
Select * from TABLEX
where DatePart(YEAR,EventDate) = 1945
It doesn't sound like the business requirement is very solidified. For what reason would you need to break out the different parts of the date? If you don't need to, then I wouldn't.
But, if you do find the necessity to do this then I'd utilize computed columns that are persisted. There wil lbe some overhead on an insert, but because there won't be any updates on existing data (your birthdate and death date won't change) then you won't see any performance overhead on a SELECT.
Something like this:
create table DateTest
(
SomeDate datetime not null,
SomeYear as datepart(yy, somedate) persisted,
SomeMonth as datepart(mm, somedate) persisted,
SomeDay as datepart(dd, somedate) persisted
)
Here is what I do.
I have a table "lib.Dates". It has a DATE as primary key.
It has additional columns with additional information to this date. This is for example day of month, day to end of month, week of year etc.
Joining this date table with dates allows me to:
* Get a list of all dates (for example grouping sales per person by date would have no entry for zero sales, this way it can have)
* Do funny things like all dates in week 23 of a year, which is normally harder to get.
This is part of a number of such tables that I have stored procedures maintain daily (-3 years, +5 years).

Query to find a weekly average

I have an SQLite database with the following fields for example:
date (yyyymmdd fomrat)
total (0.00 format)
There is typically 2 months of records in the database. Does anyone know a SQL query to find a weekly average?
I could easily just execute:
SELECT COUNT(1) as total_records, SUM(total) as total FROM stats_adsense
Then just divide total by 7 but unless there is exactly x days that are divisible by 7 in the db I don't think it will be very accurate, especially if there is less than 7 days of records.
To get a daily summary it's obviously just total / total_records.
Can anyone help me out with this?
You could try something like this:
SELECT strftime('%W', thedate) theweek, avg(total) theaverage
FROM table GROUP BY strftime('%W', thedate)
I'm not sure how the syntax would work in SQLite, but one way would be to parse out the date parts of each [date] field, and then specifying which WEEK and DAY boundaries in your WHERE clause and then GROUP by the week. This will give you a true average regardless of whether there are rows or not.
Something like this (using T-SQL):
SELECT DATEPART(w, theDate), Avg(theAmount) as Average
FROM Table
GROUP BY DATEPART(w, theDate)
This will return a row for every week. You could filter it in your WHERE clause to restrict it to a given date range.
Hope this helps.
Your weekly average is
daily * 7
Obviously this doesn't take in to account specific weeks, but you can get that by narrowing the result set in a date range.
You'll have to omit those records in the addition which don't belong to a full week. So, prior to summing up, you'll have to find the min and max of the dates, manipulate them such that they form "whole" weeks, and then run your original query with a WHERE that limits the date values according to the new range. Maybe you can even put all this into one query. I'll leave that up to you. ;-)
Those values which are "truncated" are not used then, obviously. If there's not enough values for a week at all, there's no result at all. But there's no solution to that, apparently.