SQL - User input in query - sql

I have this. "Detail all films shown by the club between any two given dates, inputted by the user. For example a club member must be able to input a start date and an end date for the parameters for the query"
Now, how would I go about doing the user input? Only way I can think of would to be using php or something with a html form getting the values and then submitting them as variables in the query. However, that's not what is needed. So, how is this done so the query would ask for values? Or can't you?
My query so far looks like so.
SELECT film.title, film.desc, show.sdate, show.fdate
FROM film
INNER JOIN show
ON film.ID=show.filmID
WHERE sdate = '&userstart' AND fdate = '&userend'
How do I go about with the user input? Also, is the query correct? I have no way of testing, I only have a design not an implementation.
Thanks a lot
Edit: Using Windows system, MS SQL Server.

Here's the code for a stored procedure:
CREATE PROCEDURE SomeName(#UserStart DATETIME, #UserEnd DATETIME)
AS BEGIN
SELECT somestuff
FROM sometable
WHERE somedate BETWEEN #UserStart AND #UserEnd
END

#Kyle93 -
Looking at your WHERE Clause:
WHERE sdate = '&userstart' AND fdate = '&userend'
This will only get you Films that had a sdate(Start Date?) equal to the date value entered.
You might want to use Greater than, Less Than operators....
Such as:
WHERE sdate <= '&userend' AND fdate >= '&userstart'
(Note comparing sdate to UserEnd Date to make sure Film Showing started EARLIER than the UserEnd Date...etc)
This way - when a show starts OR ends within the date range - it will be selected.

Are you familiar at all with LINQ? It's a way to make db calls from c#.
-- I would handle this with HTML as you thought, and use Javascript/Ajax to reference c# code that uses LINQ for db calls. Might be a bit complicated however, if you're not familiar with much of that. I can recommend good tutorials if interested tho.

Related

Where in my query to place the CONVERT to convert DateTime to Date

Just learning SQL and I've searched many options about converting a DateTime into a Date, and I do not want current date. It's a super simple query from this website: https://sqlzoo.net/wiki/Guest_House_Assessment_Easy
SELECT booking_date, nights
FROM booking
WHERE guest_id=1183
But the output is with the timestamp and I just want the date. I've searched so many forums and tried all their suggestions, including this:
SELECT CONVERT(varchar(10), <col>, 101)
So I've done:
SELECT CONVERT(varchar(10), booking_date,101), nights
FROM booking
WHERE guest_id=1183
But I'm getting syntax errors. This is probably so simple and you'll all think me an idiot, but I'd greatly appreciate help. It's driving me nuts.
When I fiddled about at your sqlzoo link I got the error
execute command denied to user 'scott'#'localhost' for routine 'gisq.to_date'`.
When I googled gisq.to_date I got this link https://sqlzoo.net/wiki/Format_a_date_and_time
Which has examples of how this dialect represents dates. See if you can work it out. Something like this:
SELECT date_format(booking_date,'%d/%m/%Y')
FROM booking
You didn't post the error in your question which is a big mistake. When you get an error message, you actually have something to work from.
It is also very important to note that the query above returns a string, not a date. It's only good for display, not for date arithmetic
TBH that seems like a terrible site to learn on as it gives no clues about the dialect. it looks like Oracle but to_date and trunc don't work.
The use of convert() suggests that you think you are uinsg SQL Server. If you only want the date component of a date/time data type, then you can use:
SELECT CONVERT(DATE, booking_date), nights
FROM booking
WHERE guest_id = 1183;
The syntax error suggests that you are not using SQL Server.
CONVERT() is bespoke syntax for SQL Server. Examples of similar functionality in other databases are:
DATE(booking_date)
TRUNC(booking_date)
DATE_TRUNC('day', booking_date)
In addition, what you see also depends on the user-interface.
In your case, the data is being stored as a date with no time component, but the UI is showing the time. For that, you want to convert to a string. That site uses MariaDB -- which is really a flavor of MySQL-- and you would use:
DATE_FORMAT(booking_date, '%Y-%m-%d')

Access SQL Query using BETWEEN Statement and dates from a form

I'm probably missing something basic here, but I can't for the life of me get this working.
I have a database that is tracking when certain projects are completed, and I want to be able to show in a list the completed projects between a date range.
The date range to check between is set by the user on a form.
I have built a query in Access:
SELECT Logs.Completed
FROM Logs
WHERE Logs.Completed BETWEEN Forms!UIBrowseCompleted!Text53 AND Forms!UIBrowseCompleted!Text55
ORDER BY Logs.Completed;
I have got the dates formatted in the text box so they are in #MM/DD/YYYY# format (I have manually put these dates direct in the query and this works) but when I run the query I get the following error:
This expression is typed incorrectly, or it is too complex to be evaluated. For example, a numeric expression may contain too many complicated elements. Try simplifying the expression by assigning parts of the expression to variables.
I have tried modifying the query to take the # out of the text fields in the form, and including ' around the Forms!UIBrowseCompleted!Text53 but I've still not got any joy from it.
has anyone had this issue before, or can anyone point me in the right direction.
Thanks
Do you want MS Access query or SQL query?
If you want MS Access query then you can try with following
SELECT Logs.Completed
FROM Logs
WHERE Logs.Completed >= Forms!UIBrowseCompleted!Text53 AND Logs.Completed <= Forms!UIBrowseCompleted!Text55
ORDER BY Logs.Completed;
between query will take time normally we use >= and <= to check date range
like
>= Forms!UIBrowseCompleted!Text53 AND Logs.Completed <= Forms!UIBrowseCompleted

oracle sql developer(4.0.0.12) returns wrong date

It seems that a query of mine returns wrong results, and I'm not sure why. I don't yet rule out the possibility that the SQL is actually doing something else then what I expect/want it to do since I haven't used SQL for a time now.
I post it here because I'm kind a stuck with the why it returns wrong results sometimes.
The error is in the MIN(FIRM.account_recharge.X__INSDATE) (or at least the ones I noticed)
SELECT
FIRM.customer.CUSTOMER_ID,
FIRM.customer.CORPORATION,
FIRM.customer.CUSTOMER_NAME_PREFIX,
FIRM.customer.CUSTOMER_NAME,
FIRM.account.ACCOUNT_TYPE,
FIRM.account.ACCOUNT_TYPE,
FIRM.customer.LANGUAGE,
FIRM.customer.VALIDATED,
FIRM.account.X__INSDATE,
SUM(FIRM.account_recharge.GROSS_VALUE) SUM_FELTOLTESEK,
MIN(FIRM.account_recharge.X__INSDATE),
INNER JOIN FIRM.account
ON FIRM.customer.CUSTOMER_ID = FIRM.account.CUSTOMER
INNER JOIN FIRM.customer_address
ON FIRM.account.CUSTOMER = FIRM.customer_address.CUSTOMER
INNER JOIN FIRM.account_recharge
ON FIRM.account.ACCOUNT_ID = FIRM.account_recharge.ACCOUNT
GROUP BY FIRM.customer.CUSTOMER_ID,
FIRM.account.X_INSDATE,
FIRM.customer.CORPORATION,
etc,etc
HAVING MIN(FIRM.account_recharge.X__INSDATE) BETWEEN to_date('2014-JAN. -01','YYYY-MON-DD') AND to_date('2014-DEC. -31', 'YYYY-MON-DD');
This code should return information abut our customers, their sum account 'recharging'/'replenishing'/'paying in' , sorry not sure of what word to use here. and their first payment/money upload to their account in 2014. Yet sometimes the return values seems to just ignore the actual first time our client paid in money, and shows the second or third date. (my random manual check returned that around 1/10 of the time the returned values are wrong.)
A costumer of ours can have more the one account linked to him. I'm using Oracle SQL developer (4.0.0.12) please ask if you would like to know anything else about this pickle im in.
Otherwise It seems to work nicely, but if you have any other tuning tip, I would be glad to hear them.
Thank you for your help!
HAVING MIN(FIRM.account_recharge.X_INSDATE) BETWEEN '14-JAN. -01' AND '14-DEC. -31'
This is definitely incorrect. You are comparing dates. so, you must convert the string literal explicitly into a date using TO_DATE and proper format mask.
For example,
HAVING MIN(FIRM.account_recharge.X_INSDATE)
BETWEEN to_date('2014-JAN-01','YYYY-MON-DD')
AND to_date('2014-DEC-31', 'YYYY-MON-DD')
Also, do not use YY to denote the year. You don't have to re-invent the Y2K bug again. Always use YYYY format for an year. Else, if you are stuck with YY values for year, then use RR format. But, I would insist, always use YYYY format for year.

Constructing an sql Query to get records betwen two dates

I'm trying to filter out and report records in a database that fall between a specified date range. I'm there are other threads here on how to do something similar, but my dates are stored as date timestamps (which is why I think the issue is arising)
My current query is as follows:
"SELECT * FROM JOURNAL WHERE Date_Time>'10/10/2013 00:00:00'"
(Note that journal is the name of the table I'm pulling the data from and date_time is the field in which the date is stored. I'm aware the query doesn't quite do what I want it to yet, but I was just testing out a simpler case at first.)
When I run this query (as part of an excel macro), excel reports that it can't find any records even though I know their are records past this date. Does anyone know how to do this properly?
Edit: I've got it, it was an issue unrelated to the query (something else in the macro) Thanks so much for the help (changing the date format worked)
have you tried other date format? like this:
"SELECT * FROM JOURNAL WHERE Date_Time>'2013-10-10:00:00:00'"
A simple between statement is what you need:
SELECT * FROM JOURNAL WHERE Date_Time between '10/10/2013 00:00:00' and '[otherdate]'
You need to run this to check for one important thing: If the server is running the BETWEEN as inclusive or not. If it's inclusive, both dates are included. If not, the range will begin either before or after one or both.
I've seen SQL servers that are the same in every respect actually treat this condition differently. So it's a good idea to check that.

How could i write this code in a more performant way?

In our app people have 1 or multiple projects. These projects have a start and an end date. People have a limited amount of available days.
Now we have a page that displays the availability of a given person on a week by week basis. It currently shows 18 weeks.
The way we currently calculate the available time for a given week is like this:
def days_available(query_date=Date.today)
days_engaged = projects.current.where("start_date < ? AND finish_date > ?", query_date, query_date).sum(:days_on_project)
available = days_total - hours_engaged
end
This means that to display the page descibed above the app will fire 18(!) queries into the database. We have pages that lists the availability of multiple people in a table. For these pages the amount of queries is quickly becomes staggering.
It is also quite slow.
How could we handle the availability retrieval in a more performant manner?
This is quite a common scenario when working with date ranges in an entity. Easy and fastest way is in SQL:
Join your events to a number generated date table (see generate days from date range) so that you have a row for each day a person or people are occupied. Once you have the data in this form it is simply a matter of grouping by the week date part of the date and counting the rows per grouping.
You can extend this to group by person for multiple person queries.
From a SQL point of view, I'd advise using a stored procedure and pass in your date/range requirement, you can then return a recordset for a user or possibly multiple users. This way your code just has to access db once.
You can then output recordset data in one go, by iterating through.
Hope this helps.
USE Stored procedure to fire your query to SQL to get data.
Pass paramerts in your case it is today's date to the SQl query.
Apply your conditions and Logic in the SQL Stored procedure , Using procedure is the goood and fastest way to retrieve data from the SQL , also it will prevent your code from the SQL injection too.
Call that SP from your Code as i dont know the Ruby on raisl I cant provide you steps about how to Call the Stored procedure from it.
After that the data fdetched as per you stored procedure will be available in Data table or something like that.
After getting the data you can perform all you need
Hope this helps
see what query is executed. further you may make comand explain to your query
explain select * from project where start_date < any_date and end_date> any_date2
you see the plan of query . Use this plan to optimized your query.
for example :
if you have index using field end_date replace a condition(end_date> any_date2 and start_date < any_date) . this step will using index if you have index on this field. But it step is db dependent . example is for nysql. if you want use index in mysql you must have using index condition on left part of where
There's not really enough information in your question to know exactly what you're trying to achieve here, e.g. the code snippet doesn't make use of the returned database query, so you could just remove it to make it faster. Perhaps this is just a bug in the code you posted?
Having said that, there are some techniques you should look into to implement your functionality.
I would take a look at using data warehouse techniques. I would think of your 'availability information' as a Fact table in a star schema, with 'Dates' and 'People' as Dimension tables.
You can then use queries to get stuff like - list of users for this projects for this week, and their availability.
Data warehousing has a whole bunch of resources you can tap into to help make this perform well, but there's also a lot of terminology that can be confusing, but for this type of 'I need to slice and dice my data across several sets of things (people and time)', Data Warehousing techniques can be quite powerful.
As I dont understand ruby on rails,from sql point of view i suggest you to write a stored procedure and return a dataset.And do the necessary table operations on the dataset from front end.It will reduce the unnecessary calls to DB.