• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 329
  • Last Modified:

SQL: QUERY PREVIOUS MONTHS BID?

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
Pancake_Effect
Asked:
Pancake_Effect
  • 5
  • 3
  • 3
  • +2
4 Solutions
 
Steve WalesSenior Database AdministratorCommented:
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
 
Pancake_EffectAuthor Commented:
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
 
Steve WalesSenior Database AdministratorCommented:
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Pancake_EffectAuthor Commented:
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
 
Steve WalesSenior Database AdministratorCommented:
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
 
Alexander Eßer [Alex140181]Software DeveloperCommented:
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
 
Steve WalesSenior Database AdministratorCommented:
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
 
Alexander Eßer [Alex140181]Software DeveloperCommented:
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
 
Alexander Eßer [Alex140181]Software DeveloperCommented:
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
 
ukerandiCommented:
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
 
Steve WalesSenior Database AdministratorCommented:
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
 
ukerandiCommented:
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
 
PortletPaulCommented:
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
 
Pancake_EffectAuthor Commented:
Thanks everyone for the help, and explaining it in terms I understand. It's working great!
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 5
  • 3
  • 3
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now