|
|
|
SSC Rookie
      
Group: General Forum Members
Last Login: Wednesday, February 20, 2013 8:15 PM
Points: 40,
Visits: 385
|
|
Hi all, How do you find a group where number of rows in the group are gtr than 1 and at least one of the non grouped columns contain at least one row with a certain value?
Example:
tableA has columns name, Type, price
example data: nameA, typeA, 1.00 nameA, typeB, 2.75 nameB, typeA, 2.00 nameC, typeB, 3.00
In this example, I would need to identify a group on name where the grouping contains at least one row where Type = 'typeB'. The value in price is ultimately what I need when there is a group with count of rows > 1 AND Type = typeB, else the group should just use the price from typeA when there is no type B within a group with count of rows > 1.
--this group I need to identify since nameA contains at least one value of typeB in column Type. When typeB is present in the group, use the price from typeB nameA, typeA, 1.00 nameA, typeB, 2.75
--this is not a group, and therefore only uses the price from typeA since there is no value of typeB in column Type. nameB, typeA, 2.00
--this is not a group, and does have a typeB. Use this price. nameC, typeB, 3.00
The returned result set would only include: nameA, typeB, 2.75 nameB, typeA, 2.00 nameC, typeB, 3.00
Any help would be appreciated.
Thanks!
|
|
|
|
|
SSCrazy
      
Group: General Forum Members
Last Login: Yesterday @ 7:24 PM
Points: 2,346,
Visits: 3,192
|
|
Something like this perhaps?
DECLARE @t TABLE (Name VARCHAR(10), [TYPE] VARCHAR(10), Price MONEY)
INSERT INTO @t SELECT 'nameA', 'typeA', 1.00 UNION ALL SELECT 'nameA', 'typeB', 2.75 UNION ALL SELECT 'nameB', 'typeA', 2.00 UNION ALL SELECT 'nameC', 'typeB', 3.00
;WITH CTE AS ( SELECT Name, [TYPE], Price ,n=ROW_NUMBER() OVER (PARTITION BY Name ORDER BY CASE [TYPE] WHEN 'typeB' THEN 0 ELSE 1 END) FROM @t ) SELECT Name, [TYPE], Price FROM CTE WHERE n=1
No loops! No CURSORs! No RBAR! Hoo-uh!
INDEXing a poor-performing query is like putting sugar on cat food. Yeah, it probably tastes better but are you sure you want to eat it?
Need to UNPIVOT? Why not CROSS APPLY VALUES instead? Since random numbers are too important to be left to chance, let's generate some! Are you too recursively challenged? Splitting strings based on patterns can be fast!
|
|
|
|
|
SSC Rookie
      
Group: General Forum Members
Last Login: Wednesday, February 20, 2013 8:15 PM
Points: 40,
Visits: 385
|
|
|
|
|
|
SSCommitted
      
Group: General Forum Members
Last Login: Tuesday, January 15, 2013 11:11 AM
Points: 1,945,
Visits: 2,782
|
|
>> How do you find a group where number of rows in the group are gtr than 1 and at least one of the non grouped columns contain at least one row with a certain value? <<
Where is the DDL ? What is the key? What are the data types? Do you work with specs like this? Let's play with it and you can learn ISO-11179 rules. Here is DDL with the stuff you left out:
CREATE TABLE Vampire_Retailers (retailer_name VARCHAR(10) NOT NULL, blood_type CHAR(3)NOT NULL, PRIMARY KEY (retailer_name, blood_type blood_price DECIMAL (5,2) NOT NULL CHECK (blood_price > 0.00));
Did I guess right?
INSERT INTO Vampire_Retailers VALUES ('nameA', 'A', 1.00), ('nameA', 'B', 2.75), ('nameB', 'B', 2.00), ('nameC', 'B', 3.00);
SELECT retailer_name, 'B', blood_price FROM Vampire_Retailers AS VR WHERE blood_type = 'B'
>> In this example, I would need to identify a group on retailer_name where the grouping contains at least one row where blood_type = 'B'. The value in price is ultimately what I need when there is a group with count of rows > 1 AND blood_type = 'B', else the group should just use the price from 'B' when there is no blood_type B within a group with count of rows > 1.
I am not sure what that means in the sample data, but try this query to get those counts and then do some filtering on it.
SELECT retailer_name, blood_type, blood_price, COUNT(*) OVER (PARTITION BY retailer_name) AS inventory_cnt FROM Vampire_Retailers AS VR WHERE blood_type = 'B';
nameA, 'B', 2.75, 2 nameB, 'B', 2.00, 1 nameC, 'B', 3.00, 1
Books in Celko Series for Morgan-Kaufmann Publishing Analytics and OLAP in SQL Data and Databases: Concepts in Practice Data, Measurements and Standards in SQL SQL for Smarties SQL Programming Style SQL Puzzles and Answers Thinking in Sets Trees and Hierarchies in SQL
|
|
|
|
|
SSC Rookie
      
Group: General Forum Members
Last Login: Wednesday, February 20, 2013 8:15 PM
Points: 40,
Visits: 385
|
|
For this,
SELECT retailer_name, blood_type, blood_price, COUNT(*) OVER (PARTITION BY retailer_name) AS inventory_cnt FROM Vampire_Retailers AS VR WHERE blood_type = 'B';
Wouldn't you instead get nameA, 'B', 2.75, 1 and not nameA, 'B', 2.75, 2 due to the where clause?
|
|
|
|
|
SSC Eights!
      
Group: General Forum Members
Last Login: Yesterday @ 4:59 PM
Points: 960,
Visits: 1,924
|
|
|
|
|
|
Ten Centuries
      
Group: General Forum Members
Last Login: Wednesday, May 22, 2013 3:56 PM
Points: 1,324,
Visits: 1,778
|
|
Any of that seems like overkill to me for the specific problem stated. Why not just?:
SELECT name, ISNULL(MAX(CASE WHEN type = 'typeB' THEN 'typeB' END), MAX(CASE WHEN type <> 'typeB' THEN type END)) AS type, ISNULL(MAX(CASE WHEN type = 'typeB' THEN price END), MAX(CASE WHEN type <> 'typeB' THEN price END)) AS price FROM dbo.tablename GROUP BY name
SQL DBA,SQL Server MVP('07, '08, '09) One man with courage makes a majority. Andrew Jackson
|
|
|
|
|
SSCrazy
      
Group: General Forum Members
Last Login: Yesterday @ 7:24 PM
Points: 2,346,
Visits: 3,192
|
|
|
|
|
|
SSC Rookie
      
Group: General Forum Members
Last Login: Wednesday, February 20, 2013 8:15 PM
Points: 40,
Visits: 385
|
|
| Thank you all for helping. The simple and direct answers gave me options for the solution. Thanks again!
|
|
|
|
|
SSC-Enthusiastic
      
Group: General Forum Members
Last Login: Thursday, May 09, 2013 7:04 AM
Points: 157,
Visits: 833
|
|
--Check this
SELECT Name,TYPE,Price FROM (SELECT Name, [TYPE], Price ,ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY PRICE DESC) AS N FROM @t) AS A WHERE N=1
|
|
|
|