Solved

SQL: QUERY PREVIOUS MONTHS BID?

Posted on 2014-04-27
14
317 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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]
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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.

Join & Write a Comment

Suggested Solutions

Configuring and using Oracle Database Gateway for ODBC Introduction First, a brief summary of what a Database Gateway is.  A Gateway is a set of driver agents and configurations that allow an Oracle database to communicate with other platforms…
How to Unravel a Tricky Query Introduction If you browse through the Oracle zones or any of the other database-related zones you'll come across some complicated solutions and sometimes you'll just have to wonder how anyone came up with them.  …
Via a live example, show how to restore a database from backup after a simulated disk failure using RMAN.
This video shows how to configure and send email from and Oracle database using both UTL_SMTP and UTL_MAIL, as well as comparing UTL_SMTP to a manual SMTP conversation with a mail server.

763 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

6 Experts available now in Live!

Get 1:1 Help Now