Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2005 Forums
 Transact-SQL (2005)
 Select with Header and Detail tables.

Author  Topic 

smh
Yak Posting Veteran

94 Posts

Posted - 2009-01-31 : 22:05:42
Hi:

I need help with this select query.

There is a header table with headerID, vendorId.
There is a detail table with header ID and productID and vendorproductcode.

I need to find a vendorproductcode where vendorID = X and productID = y so I am joining on the header key but looking for productID in the detail table and vendorID in the header table in order to get the right vendorproductcode.

How can that be done?

Thanks for help on this.

tkizer
Almighty SQL Goddess

38200 Posts

Posted - 2009-01-31 : 22:35:18
SELECT d.vendorproductcode
FROM header h
INNER JOIN detail d
ON h.headerId = d.headerId
WHERE h.vendorID = 'X' AND d.productID = 'y'

Tara Kizer
Microsoft MVP for Windows Server System - SQL Server
http://weblogs.sqlteam.com/tarad/

Subscribe to my blog
Go to Top of Page

bklr
Master Smack Fu Yak Hacker

1693 Posts

Posted - 2009-01-31 : 23:16:54
try this too
select vendorproductcode from detail
where productID = 'y' and headerid in (select headerid from header where vendorid = 'x')

select vendorproductcode from detail d
where productID = 'y' and exists (select * from header where headerid = d.headerid)
Go to Top of Page

sodeep
Master Smack Fu Yak Hacker

7174 Posts

Posted - 2009-01-31 : 23:24:01
quote:
Originally posted by bklr

try this too
select vendorproductcode from detail
where productID = 'y' and headerid in (select headerid from header where vendorid = 'x')

select vendorproductcode from detail d
where productID = 'y' and exists (select * from header where headerid = d.headerid and vendorid = 'x' )

Go to Top of Page

tkizer
Almighty SQL Goddess

38200 Posts

Posted - 2009-02-01 : 01:14:06
The JOIN method shown in my first post is the preferred method for what has been described.

Tara Kizer
Microsoft MVP for Windows Server System - SQL Server
http://weblogs.sqlteam.com/tarad/

Subscribe to my blog
Go to Top of Page

LoztInSpace
Aged Yak Warrior

940 Posts

Posted - 2009-02-01 : 06:31:02
quote:
Originally posted by tkizer

The JOIN method shown in my first post is the preferred method for what has been described.




Depends what you want and your data. Using the join you might have to use DISTINCT.
Using IN might be better if you do not have NULLs, EXISTS might be what you want if you do.

It all depends. There are subtleties.
Go to Top of Page

smh
Yak Posting Veteran

94 Posts

Posted - 2009-02-01 : 13:42:00
I want to thank everyone for these samples. when I tried them and received some errors, I realized that maybe I did not properly explain.
There may be more than one vendorproductcode for a vendorID and a productID combination, so I want to take the most recent one.
here might be some data in both tables. The queries work correctly until I put in the order by clause: order by tblProductPurchaseHeader.purchasedate desc

I have put some sample data in the next post.
If the query was on vendorid = 4 and product ID = 2453, only the first two would fit that criteria. Then by ordering by purchdate and taking the top 1, only the first record would appear in the results.

The question is where to put the order by. In the top query when I put in the order by clause I get a "multi-part identifier could not be bound error msg"

The other queries gave similar errors.
Go to Top of Page

smh
Yak Posting Veteran

94 Posts

Posted - 2009-02-01 : 13:46:51
I notice that the data got jumbled above here it is again

header table

headerID vendorid purchdate
11 4 12/12/08
13 4 11/11/08
15 6 12/24/08
16 6 12/10/08


detail table
headerID vendorproductcode productID detailID
11 aaa 2453 1
13 bbb 2453 2
14 ccc 1234 3
15 aaa 2453 4

Go to Top of Page

sodeep
Master Smack Fu Yak Hacker

7174 Posts

Posted - 2009-02-01 : 14:04:04
[code]
--Create TV
Declare @header table
(headerID int,vendorid int, purchdate datetime)

--Prepare Sample data
Insert @header
Select 11, 4, '12/12/08' union all
Select 13, 4, '11/11/08' union all
Select 15, 6, '12/24/08' union all
Select 16, 6, '12/10/08'

--Create TV

Declare @detail table
(headerID int, vendorproductcode char(5), productID int,detailID int)

--Prepare Sample data

Insert @detail
Select 11,'aaa',2453, 1 union all
Select 13 ,'bbb', 2453, 2 union all
Select 14 ,'ccc', 1234, 3 union all
Select 15 ,'aaa', 2453, 4

-- ROLL SQL WHEEL

Select headerID ,vendorid, purchdate,headerID ,vendorproductcode ,productID ,detailID from
(
Select Row_Number() over(order by t.purchdate desc) AS ROW_ID,t.headerID ,
t.vendorid, t.purchdate,d.vendorproductcode,d.productID ,d.detailID from @header t
inner join @detail d
on t.headerID = d.headerID
Where t.vendorid =4 and d.productID = 2453
)z
where z.ROW_ID =1[/code]
Go to Top of Page

sodeep
Master Smack Fu Yak Hacker

7174 Posts

Posted - 2009-02-01 : 14:08:37
Or:

SELECT TOP 1.*
FROM Header T
INNER JOIN Detail D
ON T.HeaderId = d.HeaderID
WHERE T.VendorID = 4 AND D.ProductID = 2453
Order by T.Purcdate desc
Go to Top of Page

sodeep
Master Smack Fu Yak Hacker

7174 Posts

Posted - 2009-02-01 : 14:18:01
quote:
Originally posted by smh

I want to thank everyone for these samples. when I tried them and received some errors, I realized that maybe I did not properly explain.
There may be more than one vendorproductcode for a vendorID and a productID combination, so I want to take the most recent one.
here might be some data in both tables. The queries work correctly until I put in the order by clause: order by tblProductPurchaseHeader.purchasedate desc

I have put some sample data in the next post.
If the query was on vendorid = 4 and product ID = 2453, only the first two would fit that criteria. Then by ordering by purchdate and taking the top 1, only the first record would appear in the results.

The question is where to put the order by. In the top query when I put in the order by clause I get a "multi-part identifier could not be bound error msg"

The other queries gave similar errors.




What did you try? Show us the actual query.
Go to Top of Page

smh
Yak Posting Veteran

94 Posts

Posted - 2009-02-01 : 14:29:29
I should say that the recent one from yak knowledge works. The others worked fine too but not when I added the order by clause. That is my fault because I did not mention that I needed only one value. Here is what I did with the others. I am putting the order by clause in the wrong spot. Where should I have placed them?


SELECT d.vendorproductcode
FROM tblProductPurchaseHeader h
INNER JOIN tblProductPurchasedetail d
ON h.ProductPurchaseID = d.ProductPurchaseID
WHERE h.vendorID = 4 AND d.productID = 2413
order by tblProductPurchaseHeader.purchasedate desc

select vendorproductcode from tblProductPurchasedetail
where productID = 2413 and ProductPurchaseID in (select ProductPurchaseID from tblProductPurchaseHeader
where vendorid = 4) order by tblProductPurchaseHeader.purchasedate desc

and

select vendorproductcode from tblProductPurchasedetail d
where productID = 2413 and exists (select * from tblProductPurchaseHeader
where vendorid = 4) order by tblProductPurchaseHeader.purchasedate desc

Here is the one that works:


SELECT TOP 1 vendorproductcode (this is different from the first sample which instead does d.vendorproductcode instead of just vendorproductcode)
FROM tblProductPurchaseHeader T
INNER JOIN tblProductPurchasedetail D
ON T.ProductPurchaseID = d.ProductPurchaseID
WHERE T.VendorID = 4 AND D.ProductID = 2413
Order by T.Purchasedate desc
Go to Top of Page

sodeep
Master Smack Fu Yak Hacker

7174 Posts

Posted - 2009-02-01 : 14:30:56
quote:
Originally posted by smh

I should say that the recent one from yak knowledge works and I changed the order by to t.purchasedate desc and that works. Here is what I did with the others. I am putting the order by clause in the wrong spot:


SELECT d.vendorproductcode
FROM tblProductPurchaseHeader h
INNER JOIN tblProductPurchasedetail d
ON h.ProductPurchaseID = d.ProductPurchaseID
WHERE h.vendorID = 4 AND d.productID = 2413
order by tblProductPurchaseHeader.purchasedate desc

select vendorproductcode from tblProductPurchasedetail
where productID = 2413 and ProductPurchaseID in (select ProductPurchaseID from tblProductPurchaseHeader
where vendorid = 4) order by tblProductPurchaseHeader.purchasedate desc

and

select vendorproductcode from tblProductPurchasedetail d
where productID = 2413 and exists (select * from tblProductPurchaseHeader
where vendorid = 4) order by tblProductPurchaseHeader.purchasedate desc

Here is the one that works:


SELECT TOP 1 vendorproductcode (this is different from the first sample which instead does d.vendorproductcode instead of just vendorproductcode)
FROM tblProductPurchaseHeader T
INNER JOIN tblProductPurchasedetail D
ON T.ProductPurchaseID = d.ProductPurchaseID
WHERE T.VendorID = 4 AND D.ProductID = 2413
Order by T.Purchasedate desc




Did you try with ROW_NUMBER() function as I have shown if you are using SQL 2005?
Go to Top of Page

sodeep
Master Smack Fu Yak Hacker

7174 Posts

Posted - 2009-02-01 : 14:54:40
quote:
Originally posted by smh

I should say that the recent one from yak knowledge works. The others worked fine too but not when I added the order by clause. That is my fault because I did not mention that I needed only one value. Here is what I did with the others. I am putting the order by clause in the wrong spot. Where should I have placed them?

1)-------------------------------------------
SELECT Top 1 vendorproductcode
FROM tblProductPurchaseHeader h
INNER JOIN tblProductPurchasedetail d
ON h.ProductPurchaseID = d.ProductPurchaseID
WHERE h.vendorID = 4 AND d.productID = 2413
order by h.purchasedate desc


2)------------------------------------
select TOP 1 vendorproductcode from tblProductPurchasedetail d
where productID = 2413 and ProductPurchaseID in (select ProductPurchaseID from tblProductPurchaseHeader h
where vendorid = 4)
order by h.purchasedate desc


3)--------------------------------------------

Select TOP 1 Vendorproductcode from tblProductPurchasedetail d
where productID = 2413 and exists (select * from tblProductPurchaseHeader h
where headerid = d.headerid and vendorid = 4)
order by h.purchasedate desc


Here is the one that works:


SELECT TOP 1 vendorproductcode (this is different from the first sample which instead does d.vendorproductcode instead of just vendorproductcode)
FROM tblProductPurchaseHeader T
INNER JOIN tblProductPurchasedetail D
ON T.ProductPurchaseID = d.ProductPurchaseID
WHERE T.VendorID = 4 AND D.ProductID = 2413
Order by T.Purchasedate desc


Go to Top of Page

smh
Yak Posting Veteran

94 Posts

Posted - 2009-02-01 : 15:24:00
Yes, SoDeep, I did try that and it works fine too. Also thank you for pointing out my syntax errors witht the order by clause. Why do I get the error: The multi-part identifier "fieldname" could not be bound" in these sql's. This would be very helpful to understand so as not to have this problem again. It seems that adding to the where clause also causes the same error.

I leaving 2005 and moving to 2008 this week. I have yet to look at 2008 in detail. if it does not support the rownumber function, then I could not use that one.

Go to Top of Page

sodeep
Master Smack Fu Yak Hacker

7174 Posts

Posted - 2009-02-01 : 16:00:48
It occurs when same columnname is used in 2 or more tables. You should use table alias or name for that column to avoid that.

Yes ,ROW_NUMBER() works in SQL 2008 as well
Go to Top of Page

smh
Yak Posting Veteran

94 Posts

Posted - 2009-02-01 : 16:32:52
Would there be a reason to use this version of the query rather than using an order by clause and top 1?
Go to Top of Page

sodeep
Master Smack Fu Yak Hacker

7174 Posts

Posted - 2009-02-01 : 23:00:58
It will be much easier with it to achieve different functionality.
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2009-02-01 : 23:11:45
quote:
Originally posted by sodeep

It occurs when same columnname is used in 2 or more tables. You should use table alias or name for that column to avoid that.

Yes ,ROW_NUMBER() works in SQL 2008 as well


Not true. If columns occurs in two or more tables, the error message will be Ambiguos column name as it cant determine which table column we're referring to.
The above error message is because you either dont have the column available in table or you've not included it in the derived table definition.
Go to Top of Page

sodeep
Master Smack Fu Yak Hacker

7174 Posts

Posted - 2009-02-01 : 23:33:13
quote:
Originally posted by visakh16

quote:
Originally posted by sodeep

It occurs when same columnname is used in 2 or more tables. You should use table alias or name for that column to avoid that.

Yes ,ROW_NUMBER() works in SQL 2008 as well


Not true. If columns occurs in two or more tables, the error message will be Ambiguos column name as it cant determine which table column we're referring to.
The above error message is because you either dont have the column available in table or you've not included it in the derived table definition.



Mr Visakh,

If the column is not available then you will see error like:
invalid column name

Go to Top of Page
   

- Advertisement -