Stuck in a rut- To Loop or Not, if not, how to query?
-
Thursday, February 07, 2013 4:25 PM
Hi Guys,
I am trying to work out some logic here. No clue how to apply it in SQL.
I have a view With ID, Name, Worked_Date, Work_Type, Work_Category, Work_Location, Total_Worked_Dates_in_Table and Fees
I want to build summary Table with the Name, Worked_Dates and Total_Worked_Dates
Where If the Work_Type = 'ALPHA' ON Work_Location AND Worked_Dates Then remove all Names with Work_Type = 'BETA' on same Location and Dates If more than one Work_Type ='ALPHA' exists at Location and Date, Take the Name with Max(Total_Worked_Dates_in_Table) on it.
ELSE If Work_Type='BETA' ON Work_Location AND Worked_Date Display all Names with unique Work Category and highest Fees.
The final table should have Names and Worked Dates of people who's done Maximum Alpha work at a given time or location Or Maximum Beta work. There can be more than one category of Beta work done on same location and same time.
I am desperate to get a solution here! I am considering using While loops for each day and cycling through each event but I haven't got any idea how to do that yet.
Thanks Ajmal
Ajmal
- Edited by Ajmal88 Thursday, February 07, 2013 4:46 PM
All Replies
-
Thursday, February 07, 2013 5:11 PM
Why not use a case statement?
CASE
WHEN [some condition] THEN [do this]
WHEN [some condition] THEN [do this]
ELSE [do this]
END
-
Thursday, February 07, 2013 5:31 PM
This is what I could come up as per the conditions you indicated. See if that works or provide us some sample data and expected outputs so that it can be further tuned (as needed).
;WITH GetAlphaDataTemp AS ( SELECT ID, Name, Worked_Date, Work_Type, Work_Category, Work_Location, Total_Worked_Dates_in_Table, Fees, ROW_NUMBER() OVER(PARTITION BY Work_Location, Worked_Date ORDER BY Total_Worked_Dates_in_Table DESC) AS AlphaRanking FROM YourView -- replace with your actual view WHERE Work_Type = 'Alpha' ), GetBetaDataTemp AS ( SELECT ID, Name, Worked_Date, Work_Type, Work_Category, Work_Location, Total_Worked_Dates_in_Table, Fees, ROW_NUMBER() OVER(PARTITION BY Work_Location, Worked_Date, Work_Category ORDER BY Fees DESC) AS BetaRanking FROM YourView -- replace with your actual view WHERE Work_Type = 'Beta' ) SELECT ID, Name, Worked_Date, Work_Type, Work_Category, Work_Location, Total_Worked_Dates_in_Table, Fees FROM GetAlphaDataTemp WHERE AlphaRanking = 1 -- To get the record with highest Total_Worked_Dates_in_Table value for respective Work_Location & Worked_Date combination UNION ALL SELECT ID, Name, Worked_Date, Work_Type, Work_Category, Work_Location, Total_Worked_Dates_in_Table, Fees FROM GetBetaDataTemp Beta WHERE BetaRanking = 1 -- To get the record with highest fees for each Work_Category AND NOT EXISTS -- To not include those Beta records when Alpha for the respective date and location already exists ( SELECT 1 FROM GetAlphaDataTemp Alpha WHERE Beta.Work_Location = Alpha.Work_Location AND Beta.Worked_Date = Alpha.Worked_Date )
Thanks!- Marked As Answer by Ajmal88 Friday, February 08, 2013 11:12 AM
-
Thursday, February 07, 2013 6:37 PM
Frankly, I'm not sure I understand the description of your problem because your explenation blows. Perhaps a little harsh, but being able to describe your problem (in my experience) is paramount to being able to solve it. This is what I understand of your problem. There is a view (we'll call it "Foo") with columns:
ID
Name
Worked_Date
Work_Type
Work_Category
Work_Location
Total_Worked_Dates_in_TableYou want to create a summary table (we'll call it "Bar") with columns:
Name
Worked_Dates
Total_Worked_DatesSome assumptions I'm making:
- By "remove all names", I assume you mean you want those records deleted.
- I'm assuming "ID" (from Foo) is a primary-key.
- I assume the valid values for "Work_Type" are "ALPHA" and "BETA".
You could use a CTE, temporary table, or table variable; anything to hold the interim results why you remove the records you don't want. I'd opt for a table variable unless you're dealing with a huge amount of data. You can use a permant table if you'll be selecting the results very fequently. For my samples, I'll use a temporary table (bucking my own advice). The flow I'll use is get the results then shape the results.
--Create your temporary table INSERT INTO #Bar SELECT Name, Worked_Dates, Total_Worked_Dates FROM dbo.Foo; --Delete the crud you don't want DELETE FROM #Bar WHERE ... --Bring back the data you want SELECT ..., MAX(Total_Worked_Dates_in_Tab) FROM #Bar
You can fill in the blanks for each statement based on the logic you have in mind. The flow will probably be the same. Your delete (probably the toughest of the statements) will look something like:
WITH work_alpha_multi (Work_Type, Work_Location, Worked_Date) AS ( SELECT Work_Type, Work_Location, Worked_Date FROM #Bar WHERE Work_Type = 'ALPHA' GROUP BY Work_Type, Work_Location, Worked_Date HAVING COUNT(*) > 1 ) DELETE FROM #Bar WHERE ID IN (SELECT ID FROM #Bar INNER JOIN work_alpha_multi wam ON #Bar.Work_Location = wam.Work_Location AND #Bar.Worked_Date = wam.Worked_Date) GO
Or, at least I presume it will.
Good Luck Dude,
CA-- Edited by Crazy Adam Thursday, February 07, 2013 6:37 PM
-
Friday, February 08, 2013 10:19 AM
Main Table
ID Name Worked_Date Work_Type Work Category Work_Location Total_Worked_Dates Fees
1 Armin VD 12-12-2012 ALPHA XYZ DUBAI 2 50
2 Armin VD 13-12-2012 ALPHA XYZ DUBAI 2 50
3 Bonnie L 13-12-2012 BETA AVG DUBAI 3 70
4 Bonnie L 14-12-2012 BETA AVG DUBAI 3 70
5 Bonnie L 15-12-2012 BETA AVG DUBAI 3 70
6 Amen TT 15-12-2012 BETA XYZ DUBAI 2 50
7 Amen TT 16-12-2012 BETA XYZ DUBAI 2 50
8 Amen TT 17-12-2012 BETA XYZ DUBAI 2 50
9 Downing 15-12-2012 BETA XYZ DUBAI 2 40
10 Downing 16-12-2012 BETA XYZ DUBAI 2 40
11 Ryver 13-12-2012 ALPHA XYZ DUBAI 1 40
Expected Result
1 Armin VD 12-12-2012 ALPHA XYZ DUBAI 2 50
2 Armin VD 13-12-2012 ALPHA XYZ DUBAI 2 50
4 Bonnie L 14-12-2012 BETA AVG DUBAI 3 70
5 Bonnie L 15-12-2012 BETA AVG DUBAI 3 70
6 Amen TT 15-12-2012 BETA XYZ DUBAI 2 50
7 Amen TT 16-12-2012 BETA XYZ DUBAI 2 50
8 Amen TT 17-12-2012 BETA XYZ DUBAI 2 50
I hope that clears up any confusion!
I think Deepak's answer solves it neater than what I had initially planned to do.
Ajmal
Ajmal
-
Friday, February 08, 2013 11:04 AMCheck out the table
Ajmal
-
Friday, February 08, 2013 11:12 AM
Hi Deepak,
Thanks Bud. Your answer is the best so far and it works very well!
Ajmal
-
Friday, February 08, 2013 6:41 PM
Please post DDL, so that people do not have to guess what the keys, constraints, Declarative Referential Integrity, data types, etc. in your schema are. Learn how to follow ISO-11179 data element naming conventions and formatting rules. Temporal data should use ISO-8601 formats. Code should be in Standard SQL as much as possible and not local dialect.
This is minimal polite behavior on SQL forums. How you do program from what you posted? We do not have table or column names!!
--CELKO-- 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

