Showing posts with label product. Show all posts
Showing posts with label product. Show all posts

Thursday, March 8, 2012

Complex SQL Query.

Ok,

Table Structure :

FileProduct
===========

ID int -> Unique Key (Long Integer)
FileProduct Text -> Description of product.

FileDetails
===========

ID int -> Unique Key (Long Integer)
ProductID Text -> Relational Link into the FileProduct Table above.
Filename Text -> Name of the file.
Version Text -> Version Details of File.

PCDetails
=========

ID int -> Unique Key (Long Integer)
PCName Text -> Name of PC
FileName Text -> FileName found on PC.
Version Text -> Version Details.

Table Data (what is in each table):

FileProduct
===============
ID FileProduct
-- --
1 P1

File Details
===============
ID ProductID Filename Version
-- -- -
1 1 F1.DAT 1
2 1 F1.DAT 2
3 1 F3.DAT 2
4 1 F4.DAT 2

PCDetails
=========
ID PCName FileName Version
-- -- -
1 PC1 F1.DAT 2
2 PC1 F3.DAT 2
3 PC1 F4.DAT 2
4 PC2 F1.DAT 1
5 PC2 F3.DAT 2
6 PC2 F6.DAT 3

Ok now here is the problem. What I am trying to do is
how to make a SQL statment that will return every PCName
that has has the items in the FileProduct.

Ok here is how I would like it processed

Any file with the same name would be joined by an OR condition.

So the logic would be.

If the PC record has (F1.DAT - Version 1 OR F1.DAT - Version 2) AND (F3.DAT - Version 2)
and (F4.DAT - Version 2) then it would be a succesfull match and return PC1.
So as you can see files with the same name are ORed together and files with different
names are ANDed together.

In the PC Details this would match rows 1,2 and 3. However, PC2 would not be matched
because it does not have a match for F4.DAT.

Now a Product could have mulltiple files in it and there would be multiple products.

I figure this is possible with some magic SQL - but I can't figure it out..
My instincts say this is possible with just a SQL statement.

Any help greatly appreciated !!! :)

Thanks,

Ward.


Ok, a little tricky, but if you infer from the requirement that you want to match PCs that have matching files and versions (or some version of a file) you could do something like this

Code Snippet

select * from pcdetails a

where ([filename] in (select [filename] from filedetails) and version in (select version from filedetails where [filename] = a.filename))

and (PCName not in (select PCName from pcdetails where version not in (select version from filedetails)))

The above, given the table structures and test data you provided returns this result:

Code Snippet

ID PCName FileName Version

1 PC1 F1.DAT 2

2 PC1 F3.DAT 2

3 PC1 F4.DAT 2

Maybe this will get you kick-started. I know it doesn't solve this issue of if a PC doesn't have all the files on it, but you should be able to figure that out with a little time.

Hope this at least helps.

|||

Code Snippet

select PCName
from (
select distinct PCName
from PCDetails
) as PCDetails
where not exists ( -- where there is no...
select * from [File Details] -- ...Filename/version in File Details...
where not exists ( -- ...that does not appear (note ANDs below) ...
select *
from PCDetails as P2 -- ...in PCDetails...
where P2.PCName = PCDetails.PCName -- ...for that particular PCName
and P2.FileName = [File Details].Filename
and P2.Version = [File Details].Version
)
)


This is my guess as to what you want.

Strategy:
Select PCNames for which there is no "missing" file/version.
More specifically:
Select from among the distinct PCNames in PCDetails
those PCNames for which not one of the Filename/versions
present in File Details fails to appear for that
particular PCName in PCDetails.

Steve Kass
Drew University
http://www.stevekass.com

Saturday, February 25, 2012

Complex Price List

I need help with an odd request. I have been asked to create a view
price list that includes the price each customer will pay for any
product. ProductID, customerID, and price is all I really need. Our
rules for figuring out who pays what, is somewhat complex, and I would
prefer to avoid cursoring throught what will be millions of records if
possible. In order of presidence, if there is a specific customer
price we allways use that number. Here is what the tables look like:
Customers
CustomerID CustomerName PriceListID ...
27 Acme, Inc. 1
35 Bonzi, LLC 1
41 Chuck Corp. 2
Products
ProductID ProductName ...
10 Widget
11 Thingy
12 Watchamacallit
CustPrice
CustomerID ProductID Price
27 10 2.99
41 11 10.00
35 12 30.00
If that was the end of the story my view would match the CustPrice
table, but there is a pricelist that we use if there is no special
pricing for the customer. If the price list does include the productid
in question, we use the Retail price, if the Retail price also does not
include the product then set the price to $1000 because it is a special
negotable item. This is how the product pricing tables look:
PriceLists
PriceListID PriceListName
1 Retail
2 Preferred Customer
PriceListItems
PriceListID ProductID Price
1 10 7.99
1 11 15.00
2 10 6.99
I have added a discription to show where the price came from.What my
veiw should look like in the end is this:
CustomerID ProductID Price
27 10 2.99 --Customer price
27 11 15.00 --retail
pricelist
27 12 1,000.00 --Default price
35 10 7.99 --retail
pricelist
35 11 15.00 --retail
pricelist
35 12 30.00 --Customer price
41 10 7.99 --retail
pricelist
(used because there no
preferred pricelist for the item)
41 11 10.00 --Preferred
pricelist
41 12 1,000.00 --Default price
The big question is how do I correlate customers and products with
three different pricing systems'
Please Help!roger@.wwstar.com wrote:
> I need help with an odd request. I have been asked to create a view
> price list that includes the price each customer will pay for any
> product. ProductID, customerID, and price is all I really need. Our
> rules for figuring out who pays what, is somewhat complex, and I would
> prefer to avoid cursoring throught what will be millions of records if
> possible. In order of presidence, if there is a specific customer
> price we allways use that number. Here is what the tables look like:
> Customers
> CustomerID CustomerName PriceListID ...
> 27 Acme, Inc. 1
> 35 Bonzi, LLC 1
> 41 Chuck Corp. 2
> Products
> ProductID ProductName ...
> 10 Widget
> 11 Thingy
> 12 Watchamacallit
> CustPrice
> CustomerID ProductID Price
> 27 10 2.99
> 41 11 10.00
> 35 12 30.00
> If that was the end of the story my view would match the CustPrice
> table, but there is a pricelist that we use if there is no special
> pricing for the customer. If the price list does include the productid
> in question, we use the Retail price, if the Retail price also does not
> include the product then set the price to $1000 because it is a special
> negotable item. This is how the product pricing tables look:
> PriceLists
> PriceListID PriceListName
> 1 Retail
> 2 Preferred Customer
> PriceListItems
> PriceListID ProductID Price
> 1 10 7.99
> 1 11 15.00
> 2 10 6.99
> I have added a discription to show where the price came from.What my
> veiw should look like in the end is this:
> CustomerID ProductID Price
> 27 10 2.99 --Customer price
> 27 11 15.00 --retail
> pricelist
> 27 12 1,000.00 --Default price
> 35 10 7.99 --retail
> pricelist
> 35 11 15.00 --retail
> pricelist
> 35 12 30.00 --Customer price
> 41 10 7.99 --retail
> pricelist
> (used because there no
> preferred pricelist for the item)
> 41 11 10.00 --Preferred
> pricelist
> 41 12 1,000.00 --Default price
> The big question is how do I correlate customers and products with
> three different pricing systems'
> Please Help!
>
This can be done with a couple of UNIONs, but you're going to have to
produce valid CREATE TABLE and INSERT statements first.
Tracy McKibben
MCDBA
http://www.realsqlguy.com|||Tracy McKibben wrote:
> This can be done with a couple of UNIONs, but you're going to have to
> produce valid CREATE TABLE and INSERT statements first.
>
> --
> Tracy McKibben
> MCDBA
> http://www.realsqlguy.com
I see how to get the custprices into the query.
I can do a join between Customers and PriceListProducts to get the
field I need, but how do I tell it to omit customer/Proct combinations
that I already have?
Then I could look up the list prices for customer/products not in the
second set, how do I do that?
Then I need to fill in all the blanks, which is beyond the scope of my
knowledge.|||If you have millions of rows maybe a function is better:
create function dbo.GetPrice (
@.CustomerID int,
@.ProductID int
) returns double
begin
declare @.Price as double
select @.Price = cp.Price
from CustPrice cp with(nolock)
where cp.CustomerID = @.CustomerID
and cp.ProductID = @.ProductID
if @.@.RowCount > 0
return @.Price
select @.Price = pli.Price
from Customers c with(nolock)
inner join PriceListItems pli
on c.PriceListID = pli.PriceListID
where c.CustomerID = @.CustomerID
and pli.ProductID = @.ProductID
if @.@.RowCount > 0
return @.Price
return 1000
end
go
This might be a little off because I'm not sure what you mean when you
said:
"If the price list does include the productid in question, we use the
Retail price "
If you still need a view then it would be like this:
select cp.CustomerID, cp.ProductID, cp.Price, 'cp' as Source
from CustPrice cp with(nolock)
union all
select c.CustomerID, pli.ProductID, pli.Price, 'pli'
from Customers c with(nolock)
inner join PriceListItems pli
on c.PriceListID = pli.PriceListID
where not exists
(select 1
from CustPrice cp with(nolock)
where cp.CustomerID = c.CustomerID
and cp.ProductID = pli.ProductID)
union all
select c.CustomerID, p.ProductID, 1000, 'default'
from Customers c with(nolock),
Products p with(nolock)
where not exists
(select 1
from CustPrice cp with(nolock)
where cp.CustomerID = c.CustomerID
and cp.ProductID = p.ProductID)
and not exists
(select 1
from PriceListItems pli with (nolock)
where pli.PriceListID = c.PriceListID
and pli.ProductID = p.ProductID)
Indexes would be important with this code.
JJ|||Lets think this through. Since it appears you want every customer
against every product, I would start with a cross join between
Customers and Products
FROM (SELECT * FROM Customers CROSS JOIN Products) as Crossed
We need customer prices for all the rows returned by that. We will
use a LEFT OUTER JOIN so that we don't loose any of the above rows.
FROM (SELECT * FROM Customers CROSS JOIN Products) as Crossed
LEFT OUTER
JOIN CustPrice as CP
ON Crossed.ProductID = CP.ProductID
AND Crossed.CustomerID = CP.CustomerID
That has all the rows we need prices for, with the highest priority
pricess (if any). But we also sometimes need prices from the default
PriceListItems. That calls for another LEFT OUTER JOIN. Note that it
is joining to Crossed.
FROM (SELECT * FROM Customers CROSS JOIN Products) as Crossed
LEFT OUTER
JOIN CustPrice as CP
ON Crossed.ProductID = CP.ProductID
AND Crossed.CustomerID = CP.CustomerID
LEFT OUTER
JOIN PriceListItems as PI
ON Crossed.ProductID = PI.ProductID
AND Crossed.PriceListID = CI.PriceListID
With that we should have what we need to build the SELECT list:
SELECT Crossed.CustomerID, Crossed.ProductID,
COALESCE(CP.Price, CI.Price, 1000.00)
FROM (SELECT * FROM Customers CROSS JOIN Products) as Crossed
LEFT OUTER
JOIN CustPrice as CP
ON Crossed.ProductID = CP.ProductID
AND Crossed.CustomerID = CP.CustomerID
LEFT OUTER
JOIN PriceListItems as PI
ON Crossed.ProductID = PI.ProductID
AND Crossed.PriceListID = CI.PriceListID
ORDER BY Crossed.CustomerID, Crossed.ProductID
At least I think so. Without tables and test data this is untested,
but I believe the approach is correct.
Roy Harvey
Beacon Falls, CT
On 9 Aug 2006 13:21:53 -0700, roger@.wwstar.com wrote:
>I need help with an odd request. I have been asked to create a view
>price list that includes the price each customer will pay for any
>product. ProductID, customerID, and price is all I really need. Our
>rules for figuring out who pays what, is somewhat complex, and I would
>prefer to avoid cursoring throught what will be millions of records if
>possible. In order of presidence, if there is a specific customer
>price we allways use that number. Here is what the tables look like:
>Customers
>CustomerID CustomerName PriceListID ...
>27 Acme, Inc. 1
>35 Bonzi, LLC 1
>41 Chuck Corp. 2
>Products
>ProductID ProductName ...
>10 Widget
>11 Thingy
>12 Watchamacallit
>CustPrice
>CustomerID ProductID Price
>27 10 2.99
>41 11 10.00
>35 12 30.00
>If that was the end of the story my view would match the CustPrice
>table, but there is a pricelist that we use if there is no special
>pricing for the customer. If the price list does include the productid
>in question, we use the Retail price, if the Retail price also does not
>include the product then set the price to $1000 because it is a special
>negotable item. This is how the product pricing tables look:
>PriceLists
>PriceListID PriceListName
>1 Retail
>2 Preferred Customer
>PriceListItems
>PriceListID ProductID Price
>1 10 7.99
>1 11 15.00
>2 10 6.99
>I have added a discription to show where the price came from.What my
>veiw should look like in the end is this:
>CustomerID ProductID Price
>27 10 2.99 --Customer price
>27 11 15.00 --retail
>pricelist
>27 12 1,000.00 --Default price
>35 10 7.99 --retail
>pricelist
>35 11 15.00 --retail
>pricelist
>35 12 30.00 --Customer price
>41 10 7.99 --retail
>pricelist
> (used because there no
>preferred pricelist for the item)
>41 11 10.00 --Preferred
>pricelist
>41 12 1,000.00 --Default price
>The big question is how do I correlate customers and products with
>three different pricing systems'
>Please Help!|||JJ,
That did great! Thanks!
There is the one part that I didn't explain properly that I still need
to figure out.
I wrote:
> "If the price list does include the productid in question, we use the
> Retail price "
I should have wrote:
"If the price list does NOT include the productid in question, we use
the
Retail price "
Meaning, if Bob is to use the preferred customer price list, but he
buys a "thingy" which is not on the preferred customer pricelist
(PriceListID=2), the price Bob will be charged is the retail price
(PriceListID=1).
Thanks for your help,
Roger|||if the rule is that the customer allways gets the lower price of any
that are available to him, then the code should be:
--Replace the middle "union all" block with:
union all
select c.CustomerID, pli.ProductID, min(pli.Price) as Price, 'pli'
from Customers c with(nolock)
inner join PriceListItems pli with(nolock)
on c.PriceListID = pli.PriceListID
where not exists
(select 1
from CustPrice cp with(nolock)
where cp.CustomerID = c.CustomerID
and cp.ProductID = pli.ProductID)
group by c.CustomerID, pli.ProductID
If the customer would get the "preferred price" even if it was higher
then
--need to replace the middle "union all" block with this block:
union all
select c.CustomerID, pli.ProductID, pli.Price, 'pli'
from Customers c with(nolock)
inner join PriceListItems pli with(nolock)
on c.PriceListID = pli.PriceListID
inner join (select m.ProductID, max(m.PriceListID) maxPriceListID
from PriceListItems m with(nolock)
group by m.ProductID) as m
on c.PriceListID = m.MaxPriceListID
where not exists
(select 1
from CustPrice cp with(nolock)
where cp.CustomerID = c.CustomerID
and cp.ProductID = pli.ProductID)
the first one will perform better if that is the rule. It happens we
can get away with "max(m.PriceListID)" because this is a simple
example, but usually you would add a column in the PriceList table like
"Priority" and then join to the PriceList table and take a max of
that.
I still like the function idea better especially if you are only
usually pulling back a list once you have the CustomerID already
select. It is easier to maintain.
You can still use it in a select
select CustomerID, ProductID, dbo.GetPrice(CustomerID, ProductID) as
price
from ...
where CustomerID = @.CustomerID
Put me on the preferred customer list.
JJ|||On 9 Aug 2006 15:49:01 -0700, roger@.wwstar.com wrote:
>There is the one part that I didn't explain properly that I still need
>to figure out.
>I wrote:
>> "If the price list does include the productid in question, we use the
>> Retail price "
>I should have wrote:
>"If the price list does NOT include the productid in question, we use
>the
>Retail price "
>Meaning, if Bob is to use the preferred customer price list, but he
>buys a "thingy" which is not on the preferred customer pricelist
>(PriceListID=2), the price Bob will be charged is the retail price
>(PriceListID=1).
OK so we have to make some more changes. We will do yet another outer
join to pick up PriceListID=1. And the COALESCE will have the result
from that query inserted before the ultimate default.
SELECT Crossed.CustomerID, Crossed.ProductID,
COALESCE(CP.Price, CI.Price, PL1.Price, 1000.00)
FROM (SELECT * FROM Customers CROSS JOIN Products) as Crossed
LEFT OUTER
JOIN CustPrice as CP
ON Crossed.ProductID = CP.ProductID
AND Crossed.CustomerID = CP.CustomerID
LEFT OUTER
JOIN PriceListItems as PI
ON Crossed.ProductID = PI.ProductID
AND Crossed.PriceListID = CI.PriceListID
LEFT OUTER
JOIN PriceListItems as PL1
ON Crossed.ProductID = PL1.ProductID
AND PL1.PriceListID = 1
ORDER BY Crossed.CustomerID, Crossed.ProductID
There is another approach that might be worth considering. Start with
the idea that price list 1 and price list 2 are universal, so we can
join to them directly from the Products table BEFORE the cross join.
We would then have to reference them conditionally in the results.
Since the query is getting kind of hairy, I am going to use a view for
readability sake.
CREATE VIEW ProductsStdPrices
AS
SELECT P.*,
PL1.Price as PL1_Price,
PL2.Price as PL2_Price
FROM Products
LEFT OUTER
JOIN PriceListItems as PL1
ON P.ProductID = PL1.ProductID
AND PL1.PriceListID = 1
LEFT OUTER
JOIN PriceListItems as PL2
ON P.ProductID = PL2.ProductID
AND PL2.PriceListID = 2
GO
Now we substitute the view for the Products table in the cross join,
chop off the last two outer joins, and change the COALESCE. The
change to the COALESCE would have required at least one CASE
expression put inside it, so I opted to replace the entire thing with
a CASE.
SELECT Crossed.CustomerID, Crossed.ProductID,
CASE WHEN CP.Price IS NOT NULL
THEN CP.Price
WHEN Crossed.PriceListID = 2
AND Crossed.PL2_Price IS NOT NULL
THEN Crossed.PL2_Price
WHEN Crossed.PL1_Price IS NOT NULL
THEN Crossed.PL1_Price
ELSE 1000.00
END
FROM (SELECT * FROM Customers
CROSS JOIN ProductsStdPrices) as Crossed
LEFT OUTER
JOIN CustPrice as CP
ON Crossed.ProductID = CP.ProductID
AND Crossed.CustomerID = CP.CustomerID
ORDER BY Crossed.CustomerID, Crossed.ProductID
Which again, I think will work, but is untested.
Roy Harvey
Beacon Falls, CT

Sunday, February 12, 2012

comparison Sybase Adaptive server 9 and MS SQL Server 2005

Hello
for a new product, we need to make a choice between Sybase ASA 9 (that
we know) annd MS SQL server 2005.
Does someone have a comparison available?
Is SQL server that much better than Sybase and how?
TIA
Mario"sledge" <Witdoek@.gmail.com> wrote in message
news:1190311113.772701.67030@.r29g2000hsg.googlegroups.com...
> Hello
> for a new product, we need to make a choice between Sybase ASA 9 (that
> we know) annd MS SQL server 2005.
> Does someone have a comparison available?
> Is SQL server that much better than Sybase and how?
Why are you not **at least** comparing current versions? ASA is now at
version 10 - and this isn't the enterprise-level dbms. I'm sure that you
can find plenty of opinions and documents advocating each. IMO - any dbms
provided by a major vendor will be sufficient for most needs. In any event,
there is no substitute for an actual evaluation if you REALLY need to choose
the best one for your environment.