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)
 Query with min values and max values...

Author  Topic 

iulianionescu
Starting Member

14 Posts

Posted - 2007-06-25 : 14:13:28
I have a layout that kind of looks like this:

Table1: NutDef with NutrientID and NutrientName
Table2: FoodDef with FoodID and FoodName
Table3: Nutrients with FoodID, NutrientID and Value

Each food can have 1, more or all nutrients defined in the Nutrients table.

I have a form where the user can search foods based on the contents of nutrients as follows:

show foods that are highest in: ___(val1)
and: ___(val2)
and: ___(val3)
and are lowest in: ___ (val4)
and: ___ (val5)
and: ___ (val6)

In other words, to search for foods that have highest 1, 2 or 3 nutrients but lowest in other 1, 2 or 3 nutrients.

The query received as params the 6 values. If a value is 0 it means to disregard it.

I am at a loss as how I can create a query that looks up in the Nutrient table and selects only those foods that are high in the val1, val2, val3 nutrients but lowest in val4, val5, val6 nutrients.

Any idea? I will manage to create the special cases to handle the 0 value but I need to understand how to create the main query first...

Any help will be appreciated,

Thank you,




Regards,

Iulian

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2007-06-25 : 15:02:03
Something like this?
-- Prepare sample data
DECLARE @NutDef TABLE (NutrientID INT, NutrientName VARCHAR(20))

INSERT @NutDef
SELECT 4, 'Natrium' UNION ALL
SELECT 6, 'Water'

DECLARE @FoodDef TABLE (FoodID INT, FoodName VARCHAR(20))

INSERT @FoodDef
SELECT 5, 'Salt' UNION ALL
SELECT 9, 'Cucumber'

DECLARE @Nutrients TABLE (FoodID INT, NutrientID INT, Value SMALLMONEY)

INSERT @Nutrients
SELECT 5, 4, .83 UNION ALL
SELECT 9, 4, .01 UNION ALL
SELECT 9, 6, .98

-- Prepare parameters
DECLARE @Val1 INT,
@Val2 INT,
@Val3 INT,
@Val4 INT,
@Val5 INT,
@Val6 INT

SELECT @Val1 = 6,
@Val2 = 0,
@Val3 = 0,
@Val4 = 0,
@Val5 = 4,
@Val6 = 0

-- Show the expected output
SELECT hi.FoodID,
fd.FoodName
FROM (
SELECT FoodID,
ROW_NUMBER() OVER (PARTITION BY FoodID ORDER BY Value DESC) AS HighRec
FROM @Nutrients
WHERE NutrientID IN (@Val1, @Val2, @Val3)
) AS hi
INNER JOIN (
SELECT FoodID,
ROW_NUMBER() OVER (PARTITION BY FoodID ORDER BY Value) AS LowRec
FROM @Nutrients
WHERE NutrientID IN (@Val4, @Val5, @Val6)
) AS lo ON lo.FoodID = hi.FoodID
INNER JOIN @FoodDef AS fd ON fd.FoodID = hi.FoodID
WHERE hi.HighRec = 1
AND lo.LowRec = 1


Peter Larsson
Helsingborg, Sweden
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2007-06-25 : 15:37:43
Here is another approach which will work in SQL 2000 too.
-- Show the expected output again
SELECT n.FoodID,
fd.FoodName
FROM @Nutrients AS n
INNER JOIN @FoodDef AS fd ON fd.FoodID = n.FoodID
GROUP BY n.FoodID,
fd.FoodName
HAVING MIN(n.Value) = MIN(CASE WHEN n.NutrientID IN (@Val4, @Val5, @Val6) THEN n.Value END)
AND MAX(n.Value) = MAX(CASE WHEN n.NutrientID IN (@Val1, @Val2, @Val3) THEN n.Value END


Peter Larsson
Helsingborg, Sweden
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2007-06-25 : 17:33:36
I have a dilemma.
Execution plans reveals second query is much more efficient. But Profilers says first query is more efficient since it has only 5 reads and second query has 9 reads.


Peter Larsson
Helsingborg, Sweden
Go to Top of Page
   

- Advertisement -