Solved

SQL: QUERY PREVIOUS MONTHS BID?

Posted on 2014-04-27
14
320 Views
Last Modified: 2014-04-29
I'm working on a example query. So I have a CUSTOMER table and a BID table.

Basically I want to see all of our customers who receieved a bid. This is the query I'm working on:

SELECT CUSTOMER.CUST_FNAME, CUSTOMER.CUST_LNAME, BID.BID_DATE
FROM CUSTOMER C
WHERE BID.DATE beween to_date('03/01/2014','MM/DD/YYYY') and to_date('03/31/2014','MM/DD/YYYY') JOIN  BID B
ON C.CUST_NUM=B.CUST_NUM
ORDER BY C.CUST_FNAME

Open in new window



However whenever I run it, I get this error message:

ORA-01747: invalid user.table.column, table.column, or column specification

Can anyone help me fix my query?
0
Comment
Question by:Pancake_Effect
  • 5
  • 3
  • 3
  • +2
14 Comments
 
LVL 22

Expert Comment

by:Steve Wales
ID: 40026171
I the select you say "BID.BID_DATE"

In the where you say "WHERE BID.DATE between..."

Should that be BID.BID_DATE between ?

(DATE is a reserved word in Oracle, so I doubt you have a column name called DATE).
0
 
LVL 4

Author Comment

by:Pancake_Effect
ID: 40026179
I do have a column called BID_DATE...not a good thing I take it? Didn't seem to mind when I initially created it.
0
 
LVL 22

Expert Comment

by:Steve Wales
ID: 40026181
BID_DATE is fine.

DATE is not.

Look carefully at your WHERE clause as posted above

WHERE BID.DATE

Not BID_DATE, you have BID.DATE (period, not underscore)

You should have "WHERE BID_DATE between" or "WHERE BID.BID_DATE between"
0
 
LVL 4

Author Comment

by:Pancake_Effect
ID: 40026186
Ah gotcha! Changed that. Also just for the heck of it (to avoid confusion) I changed the name to BID_SENT instead of BID_DATE.

Ok, so now I got a different error though.

"ORA-00920: invalid relational operator"

Do you happen to see anything else? I'm just not seeing it:

Latest Version:

SELECT CUSTOMER.CUST_FNAME, CUSTOMER.CUST_LNAME, BID.BID_SENT
FROM CUSTOMER C
WHERE BID.BID_SENT beween to_date('03/01/2014','MM/DD/YYYY') and to_date('03/31/2014','MM/DD/YYYY') JOIN  BID B
ON C.CUST_NUM=B.CUST_NUM
ORDER BY C.CUST_FNAME

Open in new window


Just for your reference this is how I created the two tables if it helps:


CREATE TABLE BID(
BID_ID NUMBER PRIMARY KEY,
CUST_ID NUMBER,
BID_MAN_HOURS NUMBER(4,0)  NOT NULL,
BID_MATERIALS VARCHAR(1000)NOT NULL,
BID_OVERALL_PRICE FLOAT(10) NOT NULL,
BID_SENT DATE,
FOREIGN KEY (CUST_ID) REFERENCES CUSTOMER (CUST_ID)
ON DELETE CASCADE
);

Open in new window


CREATE TABLE CUSTOMER(
CUST_ID NUMBER PRIMARY KEY,
CUST_LNAME VARCHAR(20) NOT NULL,
CUST_FNAME VARCHAR(15) NOT NULL,
CUST_ADDRESS VARCHAR(35) NOT NULL,
CUST_PHONE CHAR(10) NOT NULL,
CUST_EMAIL VARCHAR(35),
CUST_BAL NUMBER(5,2) DEFAULT 0.00
);

Open in new window

0
 
LVL 22

Assisted Solution

by:Steve Wales
Steve Wales earned 250 total points
ID: 40026190
Try this:

SELECT CUSTOMER.CUST_FNAME, CUSTOMER.CUST_LNAME, BID.BID_SENT
FROM CUSTOMER C
JOIN BID B
ON C.CUST_ID=B.CUST_ID
WHERE BID.BID_SENT beween to_date('03/01/2014','MM/DD/YYYY') and to_date('03/31/2014','MM/DD/YYYY') 
ORDER BY C.CUST_FNAME

Open in new window


Columns appear to be called CUST_ID not CUST_NUM for the join condition.

Syntax is:

select ....
from ...
join ...
on ...
where ...


And by the way, using the word DATE in a column name (like BID_DATE) is perfectly fine and probably more descriptive overall.
0
 
LVL 13

Assisted Solution

by:Alexander Eßer [Alex140181]
Alexander Eßer [Alex140181] earned 250 total points
ID: 40026192
1. you have (at least) 1 typo in your query: "beween" should read "between"
2. the join should come before where clause, like
SELECT CUSTOMER.CUST_FNAME, CUSTOMER.CUST_LNAME, BID.BID_SENT
FROM CUSTOMER C JOIN  BID B
ON C.CUST_NUM=B.CUST_NUM 
WHERE BID.BID_SENT between to_date('03/01/2014','MM/DD/YYYY') and to_date('03/31/2014','MM/DD/YYYY') ORDER BY C.CUST_FNAME

Open in new window

0
 
LVL 22

Assisted Solution

by:Steve Wales
Steve Wales earned 250 total points
ID: 40026193
Also:

Use your aliases consistently:

SELECT C.CUST_FNAME, C.CUST_LNAME, B.BID_SENT
FROM CUSTOMER C
JOIN BID B
ON C.CUST_ID=B.CUST_ID
WHERE B.BID_SENT between to_date('03/01/2014','MM/DD/YYYY') and to_date('03/31/2014','MM/DD/YYYY') 
ORDER BY C.CUST_FNAME

Open in new window


You're using the alias for some and the full table name for others which may lead to confusion down the road if you ever need to come back and debug your code.
0
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 
LVL 13

Expert Comment

by:Alexander Eßer [Alex140181]
ID: 40026194
And by the way, using the word DATE in a column name (like BID_DATE) is perfectly fine and probably more descriptive overall.
I totally agree with that, plus: even if possible, try to avoid using reserved words like 'DATE' or 'TIMESTAMP' as column names!
0
 
LVL 13

Accepted Solution

by:
Alexander Eßer [Alex140181] earned 250 total points
ID: 40026197
This statement could also look like this (but in most cases, it's better to use full ANSI syntax):
SELECT  C.CUST_FNAME, C.CUST_LNAME, B.BID_SENT
  FROM  BID B, CUSTOMER C
WHERE B.CUST_ID = C.CUST_ID AND B.BID_SENT between to_date('03/01/2014','MM/DD/YYYY') and to_date('03/31/2014','MM/DD/YYYY') 
ORDER BY C.CUST_FNAME

Open in new window

0
 
LVL 10

Expert Comment

by:ukerandi
ID: 40026204
SELECT CUSTOMER.CUST_FNAME, CUSTOMER.CUST_LNAME, B.BID_DATE
FROM CUSTOMER C
LEFT OUTER JOIN BID b ON C.CUST_NUM=B.CUST_NUM and B.DATE beween to_date('03/01/2014','MM/DD/YYYY') and to_date('03/31/2014','MM/DD/YYYY')
ORDER BY C.CUST_FNAME
0
 
LVL 22

Expert Comment

by:Steve Wales
ID: 40026206
A LEFT OUTER JOIN won't give the correct result set according to the original question.

"I want to see all of our customers who receieved a bid."

LEFT OUTER JOIN will pick up customers where there were no bids as well - that is what OUTER joins do - match on missing data as well as present data.

In order to only show customers who received a bid, an INNER JOIN (which is what just using the JOIN keyword does) is needed.
0
 
LVL 10

Expert Comment

by:ukerandi
ID: 40026237
Yes I agree, its should be Inner Join
SELECT CUSTOMER.CUST_FNAME, CUSTOMER.CUST_LNAME, B.BID_DATE
FROM CUSTOMER C
INNER  JOIN BID b ON C.CUST_NUM=B.CUST_NUM and B.DATE beween to_date('03/01/2014','MM/DD/YYYY') and to_date('03/31/2014','MM/DD/YYYY')
ORDER BY C.CUST_FNAME
0
 
LVL 48

Expert Comment

by:PortletPaul
ID: 40026436
no points please

When using table aliases they should be used consistently (very good advice by Steve Wales)

If the table alias B had been used consistently in the original query
"WHERE BID.DATE beween" would have been
"WHERE B.DATE beween"

& then perhaps the advice regarding use of "date" may have been easier to follow.
Use of "date" within a field name is perfectly fine, it just should not be the field name, so "bid_date" was OK.

The misspelling of between (beween) would have caused the invalid relational operator error which Alexander Eßer identified

and as both Steve and Alexander have shown JOIN comes before the WHERE

There is one further point I'd like to make. Using BETWEEN for date ranges isn't a good idea. Please see: "Beware of Between" for more detail on why. In essence IF the field BID_SENT holds times other than 00:00:00 then your existing query logic could miss data on March 31. Below I suggest a query to test if BID_SENT does have time other than 00:00:00
-- test if time could affect the accuracy of between 
SELECT
     count(*)
FROM bid
WHERE BID_SENT <> trunc(BID_SENT)
;
	
-- If that count is > zero, then you really should use this:

SELECT
       C.CUST_FNAME
     , C.CUST_LNAME
     , B.BID_SENT
FROM CUSTOMER C
INNER JOIN BID B ON C.CUST_ID = B.CUST_ID
WHERE ( B.BID_SENT >= to_date('03/01/2014','MM/DD/YYYY') 
    AND B.BID_SENT <  to_date('04/01/2014','MM/DD/YYYY') )
ORDER BY C.CUST_FNAME
;

Open in new window

& even if that count is zero I recommend avoiding the use of between for date ranges.
0
 
LVL 4

Author Closing Comment

by:Pancake_Effect
ID: 40029714
Thanks everyone for the help, and explaining it in terms I understand. It's working great!
0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Background In several of the companies I have worked for, I noticed that corporate reporting is off loaded from the production database and done mainly on a clone database which needs to be kept up to date daily by various means, be it a logical…
Using SQL Scripts we can save all the SQL queries as files that we use very frequently on our database later point of time. This is one of the feature present under SQL Workshop in Oracle Application Express.
This video explains at a high level with the mandatory Oracle Memory processes are as well as touching on some of the more common optional ones.
This video shows how to recover a database from a user managed backup

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now