Parsing Attribute Data from Column- SQL Server - sql-server

I have a table with column "Long Description" typically the data looks like the following.
Foundation area wall, 12" H. x 20" W. x 8" projection. Galvanized. Refer to model No. SV208 (SKU 100002) for foundation area wall cover. No. FV208-12: Height: 12", Width: 20", Projection: 8", Type: Foundation Area Wall, Material: Galvanized, Pkg Qty: 1
What I am trying to do is parse out the end attributes. For example after "area wall cover." and beginning with "No." I'd like to extract the following. (Below)
Some things to note. The string '. No.' always begins the attributes in this column. All attributes are separated by columns. The attribute names differ and the amount of attributes per product also differ. Is there a way this can be done with T-SQL?
No. FV208-12:
Height: 12"
Width: 20"
Projection: 8"
Type: Foundation Area Wall
Material: Galvanized
Pkg Qty: 1

You can use a variation of the following to achieve what I believe you're attempting to achieve:
DECLARE #StartAttributesKey VARCHAR(50) = 'area wall cover. ' ,
#LongDescription VARCHAR(MAX) = 'Foundation area wall, 12" H. x 20" W. x 8" projection. Galvanized. Refer to model No. SV208 (SKU 100002) for foundation area wall cover. No. FV208-12: Height: 12", Width: 20", Projection: 8", Type: Foundation Area Wall, Material: Galvanized, Pkg Qty: 1';
SELECT REPLACE(SUBSTRING(#LongDescription, CHARINDEX(#StartAttributesKey, #LongDescription, 0) + LEN(#StartAttributesKey),
LEN(#LongDescription) - CHARINDEX(#StartAttributesKey, #LongDescription, 0)), ',', CHAR(10));
Using this in a query would be similar to:
DECLARE #StartAttributesKey VARCHAR(50) = 'area wall cover. '
SELECT REPLACE(SUBSTRING(LongDescription, CHARINDEX(#StartAttributesKey, LongDescription, 0) + LEN(#StartAttributesKey),
LEN(LongDescription) - CHARINDEX(#StartAttributesKey, LongDescription, 0)), ',', CHAR(10))
FROM [someTable] WHERE ID = 1
If you copy (or print) the result, you will see each attribute on a separate line.

Related

In a Ruby on Rails app, I'm trying to loop through an array within a hash within an array. Why am I getting "syntax error" message?

I have a Ruby on Rails application to enter results and create a league table for a football competition.
I'm trying to input some results by creating records in the database through heroku and I get error messages.
The application isn't perfectly designed: to enter the results, I have to create the fixtures and enter the score for each team. Then, independently I have to record each goal scorer, creating a record for each goal which is either associated with an existing player or requires me to firstly create a new player and then create the goal.
When I ran the code below heroku, I got this error:
syntax error, unexpected ':', expecting keyword_end
Maybe I'm missing something simple about lopping through an array within a hash?
Thank you for any advice!
coalition = Team.find_by(name: "Coalition")
moscow_rebels = Team.find_by(name: "Moscow Rebels")
red_star = Team.find_by(name: "Red Star")
unsanctionables = Team.find_by(name: "The Unsanctionables")
cavalry = Team.find_by(name: "Cavalry")
galactics = Team.find_by(name: "The Galactics")
happy_sundays = Team.find_by(name: "Happy Sundays")
hardmen = Team.find_by(name: "Hardmen")
international = Team.find_by(name: "International")
evropa = Venue.find_by(name: "Evropa")
s28 = Season.find_by(number: 28)
start_time = DateTime.new(2020,9,6,11,0,0,'+03:00')
scheduled_matches_1 =
[
{team_1: cavalry, team_1_goals: 1, team_1_scorers: ["Minaev"], team_2_goals: 6, team_2_scorers: ["Kovalev", "Kovalev", "Kovalev", "Thomas", "Thomas", "Grivachev"], team_2: coalition, time: start_time, venue: evropa, season: s28},
{team_1: hardmen, team_1_goals: 4, team_1_scorers: ["Jones", "Jones", "Jones", "Fusi"], team_2_goals: 2, team_2_scorers: ["Kazamula", "Ario"], team_2: galactics, time: start_time + 1.hour, venue: evropa, season: s28},
{team_1: international, team_1_goals: 9, team_1_scorers: ["Kimonnen", "Kimonnen", "Kimonnen", "Burya", "Burya", "Zakharyaev", "Zakharyaev", "Lavruk", "Rihter"], team_2_goals: 0, team_2_scorers: [], team_2: happy_sundays, time: start_time+2.hours, venue: evropa, season: s28}
]
scheduled_matches.each do |match|
new_fixture = Fixture.create(time: match[:time], venue: match[:venue], season: match[:season])
tf1 = TeamFixture.create(team: match[:team_1], fixture: new_fixture)
tf2 = TeamFixture.create(team: match[:team_2], fixture: new_fixture)
ts1 = TeamScore.create(team_fixture: tf1, total_goals: match{:team_1_goals})
ts2 = TeamScore.create(team_fixture: tf2, total_goals: match{:team_2_goals})
match[:team_1_scorers].each do |scorer|
if Player.exists?(team: tf1.team, last_name: scorer)
Goal.create(team_score: ts1, player: Player.find_by(last_name: scorer))
else
new_player = Player.create(team: tf1.team, last_name: scorer)
Goal.create(team_score: ts1, player: new_player)
end
end
match[:team_2_scorers].each do |scorer_2|
if Player.exists?(team: tf2.team, last_name: scorer_2)
Goal.create(team_score: ts2, player: Player.find_by(last_name: scorer_2))
else
new_player = Player.create(team: tf2.team, last_name: scorer_2)
Goal.create(team_score: ts2, player: new_player)
end
end
end
It looks like you are using braces when you meant to use brackets to access the hash. Below is one of the issues, but the same issue is in ts2.
ts1 = TeamScore.create(team_fixture: tf1, total_goals: match{:team_1_goals})
should be match[:team_1_goals]
ts1 = TeamScore.create(team_fixture: tf1, total_goals: match[:team_1_goals])
It may be because you have scheduled_matches_1 at the top and scheduled_matches.each do... further down.
But the real issue here is that your variable names match the data content, rather than being used to hold the content. If a new team joins your league, you have to change the code. Next week, you are going to have to change the hard-coded date value. Your scheduled_matches_1 data structure includes the active record objects returned by the first set of Team.findByName() calls. It would be easier to fetch these objects from the database inside your loops, and just hold the team name as a string in the hash.
There is some duplication too. Consider that each fixture has a home team and an away team. Each team has a name, and an array (possibly empty) of the players who scored. We don't need the number of goals; we can just count the number of players in the 'scorers' array. The other attributes, like the location and season belong to the fixture, not the team. So your hash might be better as
{
"fixtures": [
{
"home": {
"name": "Cavalry",
"scorers": [
"Minaev"
]
},
"away": {
"name": "Coalition",
"scorers": [
"Kovalev",
"Kovalev",
"Kovalev",
"Thomas",
"Thomas",
"Grivachev"
]
},
"venue": "Evropa",
"season": "s28"
}
]
}
because then you can create a reusable method to process each team. And maybe create a new method that returns the player (which it either finds or creates) which can be called by the loop that adds the goals.
Also, as it stands, I'm not sure the code can handle 'own goals', either. Perhaps something for a future iteration :)

AngularFire custom order by ranking

I'm trying to sort teams by ranking, using AngularFire and Firebase.
In Firebase I have 4 teams where I store only the name.
I also store matches, which have a reference to both teams disputing that match and the score for each one.
The matches node looks like this:
matches
-KQgphN_5692GySN0Oxz
home_team: teamA
away_team: teamB
score
home: 1
away: 2
-KQlu6XLak6LgAr9cTty
home_team: teamC
away_team: teamD
score
home: 2
away: 2
And the teams node:
teams
teamA
name: "Team A"
teamB
name: "Team B"
teamC
name: "Team C"
teamD
name: "Team D"
So, I need to order these teams by vitories, draws and losses by watching the results in realtime.
I have a ng-repeat that lists teams like this:
<li ng-repeat="team in teams">{{team.name}}</li>
So, how can I order these teams by wins, taking in account that a win is equivalent to 3 points, a draw is 1 point and a loss is 0 points?
With the above matches example, the ranking should be:
1 - Team B
2 - Team C
3 - Team D
4 - Team A
You can order a Firebase Database query by a nested value, as long as that nested value is at a fixed path. This means you'll need to store the score for each team, e.g.
teams
teamA
name: "Team A"
score: 20
teamB
name: "Team B"
score: 12
teamC
name: "Team C"
score: 42
teamD
name: "Team D"
score: 31
With this structure, you can load the top teams in order with:
var leaders = ref.child('teams').orderByChild('score').limitToLast(3);
leaders.on('value', function(snapshot) {
leaders.forEach(function(leaderSnapshot) {
console.log(leaderSnapshot.child('name').val());
});
});
This will print:
Team A
Team D
Team C
So to get the leaderboard, you'll need to invert them.

Access JSON array using SuperObject

I have recently switched from using ULKJson to SuperObject and I have been looking around at the examples that come with the package and have made some headway with most it it, but it appears as I have come across a snag. To be more specific, I cannot seem to find an example to show how to access item in an array like the one in the example below.
{
"name": "John Smith",
"tel": 555-5555,
"age": 18,
"height": 1.8,
"place": [{"address": "PO Box 1234", "city": "Florida", "code": 2000},
{"address": "1 Sparrow street", "city": "Florida", "code": 2000}]
}
To access the regular items I use the following code which seems to work just fine.
procedure TForm1.Button1Click(Sender: TObject);
var
SO : ISuperObject;
age, height, tel : Integer;
name : String;
begin
SO := TSuperObject.ParseFile('JSON.txt',true);
name := SO.S['name'];
age := SO.I['age'];
tel := SO.I['tel'];
height := SO.I['height'];
Memo1.Lines.Clear;
Memo1.Lines.Add('Name: ' + name);
Memo1.Lines.Add(#10#13);
Memo1.Lines.Add('Age: ' + age);
Memo1.Lines.Add(#10#13);
Memo1.Lines.Add('Telephone: ' + tel);
Memo1.Lines.Add(#10#13);
Memo1.Lines.Add('Height: ' + height);
Memo1.Lines.Add(#10#13);
end;
However, I am not sure how to access the items in the Place array and I am sure I am just overlooking something simple, but I could not find any examples in the demos which showed how to access this data and was hoping one of the gurus here might be able to offer some assistance or atleast point me to a guide where I can learn from myself.
The way I would do it would be simply:
var
location:ISuperObject;
begin
for location in SO['place'] do
Memo1.Lines.Add(location.S['address']); //etc.
end;
end;
And as TLama has suggested, the short guide really is a great source to learn from.

Angular.js Select with ngOptions: Label the optgroup

I just started to play with Angular.js and have a question about ngOptions: Is it possible to label the optgroup?
Lets assume 2 objects - cars and garages.
cars = [
{"id": 1, "name": "Diablo", "color": "red", "garageId": 1},
{"id": 2, "name": "Countach", "color": "white", "garageId": 1},
{"id": 3, "name": "Clio", "color": "silver", "garageId": 2},
...
]
garages = [
{"id": 1, "name": "Super Garage Deluxe"},
{"id": 2, "name": "Toms Eastside"},
...
]
With this code I got nearly the result I want:
ng-options = "car.id as car.name + ' (' + car.color + ')' group by car.garageId for car in cars"
Result in the select:
-----------------
1
Diablo (red)
Countach (white)
Firebird (red)
2
Clio (silver)
Golf (black)
3
Hummer (silver)
-----------------
But I want to label the optgroups like "Garage 1", "Garage 2", ... or even better display the name of the garage and not just the garageId.
The angularjs.org documentation for select says nothing about labels for the optgroup, but I would like to extend the group by part of ngOptions like group by car.garageId as 'Garage ' + car.garageId or group by car.garageId as getGarageName(car.garageId) - which sadly is not working.
My only solution so far is to add a new property "garageDisplayName" to the car objects and store there the id + garage name and use that as group by parameter. But I don't want to update all cars whenever a garage name is changed.
Is there a way to label the optgroups with ngOptions, or should I use ngRepeat in that case?
You can just call getGarageName() in the group by without using an as...
ng-options="car.id as car.name + ' (' + car.color + ')' group by getGarageName(car.garageId) for car in cars"
Instead of storing the garage id in each car, you might want to consider storing a reference to the garage object in the garages array. That way you can change the garage name and there is no need to change each car. And the group by simply becomes...
group by car.garage.name

Angular select box with 2 values

I want to have a select box with a list of price range.
Example:
- 0 to $2,000
- $2,000 to $3,500
- $3,500 to $5,000
- $5,000 to $7,500
- $7,500 to $10,000
- $10,000
When the user select one option I want to set the budget range:
For instance if the user clicks on - $3,500 to $5,000 then is set the following values:
$scope.var.x = 3500;
$scope.var.y = 5000;
I would like to do this directly on a partial if possible.
That's something easy to do if you have correctly understood the Angular principles. I think that you have something like an array which contains your price ranges:
$scope.ranges = [
{start : 0, end : 2000},
{start : 2000, end : 3500},
{start : 3500, end : 5000},
{start : 5000, end : Infinity}
];
Then, simply construct your <select> menu from this array:
<select ng-model="selectedRange" ng-options="range as '$' + range.start + ' to $' + range.end for range in ranges"></select>
Fiddle
Notice that if you have just a list of price…
$scope.ranges = [0, 2000, 3500, 5000];
… it's not really difficult to reconstruct the first object I've shown.

Resources