MySQL: Merging different entities in one Query - mysql

I basically have three different classes of items that I want to show on a users wall: ratings, comments, and updates. This three are completey different entities, but because they all can appear on a users wall, I just call them "wallitem". The all have a timestamp property, which represents the date they were created.
I want to enable users to page through the wallitems, ordered by the timestamp. For example: last 10 wallitems. Or wallitems 20 to 30. Is there an MySQL Query that gives me the last 10 "wallitems", even though all different entities have different columns?
I could imagine, getting a list of items back, where each item has all the properties of all different entities, an additional property defining the type (for example "rating"), if it is in fact a rating, all other properties are just null. I would love to use such a dicationary in my php code:
foreach ($wallItemArray as $item) {
if ($item['type'] == "rating") {
$rating = $item; // use it as normal "rating"-entity
} else if ($item['type'] == "comment") {
$comment = $item; // use it as normal "comment"
}
// and so on for all different entities that could represent a wallitem in this context
}

Something like
SELECT 'rating' AS type, value AS r_val, NULL AS c_val
FROM Rating
UNION
SELECT 'comment' AS type, NULL AS r_val, comment_text AS c_val
FROM Comment
would get you started

Related

How can i adjust joined table query result in needed JSON format with CodeIngiter

Suppose we have table person and table phoneand the relation between them is one to many.
I need to retrieve this like result with one query.
[
{
name:"abc",
lname:"def",
phones:[
{
dial_code="+1",
number:"12345667"
},
{
dial_code="+1",
number:"12345667"
}
]
},
{
name:"xyz",
lname:"lmn",
phones[
{
dial_code="+2",
number:"2643525"
}
]
},
{...}
]
I can do this by multiple query like first getting all persons and then get their phones one by one but i think its so weird and need lots of time and reduce performance. and if i get all data by joining table it wouldn't be like this JSON format.
Any idea will be appreciated.
Sorry for my bad English.
First things first, you cannot retrieve the desired result with multiple phone inside each person with one single query.
Now, running the query inside person loop will hugely affect the performance of the script if there are a lot of data. In this way, first, you need to execute a query to fetch all persons(say n persons). Then you have to again loop all n persons to fetch their respective phones.
So you need to run something like following inside $persons loop n times:
SELECT * FROM phone WHERE person_id = [$person_id]
Therefore in this way you need to execute n+1 queries.
To overcome this n+1 query problem we can apply a methodology which is called as eager loading. Here you also need to execute the first query to retrieve all persons and then write a query to fetch all phones which belongs to those retrieved persons:
SELECT * FROM person
Result($persons):
id name
5 John
10 Bob
20 Jenna
SELECT * FROM phone WHERE person_id IN (5,10,20)
Result($phones):
id person_id dial_code number
1 5 +2 12345
2 10 +1 12312
3 20 +1 98765
Now we combine these two results in PHP scripts to produce the desired array. In this way, we write only two queries instead of n+1 queries.
You can write a PHP script like following to combine the two result sets:
// Create an array of phones with person_id as key
$phones_with_person_id_as_key = [];
foreach($phones as $key => $phone) {
$phones_with_person_id_as_key[$phone->person_id][$key] = $phone;
}
// Loop $persons array and add phones to person object
foreach($persons as $key => $person) {
// create phones key and add data
if (!empty($phones_with_person_id_as_key[$person->id])) {
$person->phones = $phones_with_person_id_as_key[$person->id];
}
else {
$person->phones = [];
}
}
Now $persons contains the formatted desired output.

Get all rows who have no associated data

Campaign have attributes :start_date,:end_date
Invoice have attributes :start_date,:end_date
campaign.rb
has_many:invoices
invoice.rb
belongs_to:campaign'
I want to get all campaigns who have no invoices and whose end_date is less than current date.
I tried like this
Campaign.includes(:invoices).where("compaigns.end_date > ? ",Date.today, :invoices => { :campaign_id => nil } ).count
How I do this?
I think you're almost there. The example given doesn't work because it mixes the string and hash forms of where. Try splitting the conditions into two where calls:
Campaign.includes(:invoices).
where("campaigns.end_date > ? ",Date.today).
where(invoices: {campaign_id: nil}).count

How sort json array multiple times in swift

I am trying to sort an array by a few values, not just one but three I can sort it like this
mysocialArray.sort({$0["date"] > $1["date"]})
This works fine, but i can find any where how to then sort it again so i get them sorted on time and another sort. SO should sort three times. When i just add another sort it is not taking the date into account.
The sorted json output will then be loaded in arrays as strings to display on the viewcontroller
How should I solve this?
thanks
Given your requirements of "This way the latest post that not yet have been read are at the top", looks like you are looking to sort by multiple criteria. I typed this in the dark so you may have to adjust it to fit your case:
mySocialArray.sort {
// First sort by read status. Assuming read is of type Bool
let (read1, read2) = ($0["read"] ? 1 : 0, $1["read"] ? 1 : 0)
if read1 != read2 {
return read1 > read2
}
// Then short by date. I assume date is of type NSDate
let (date1, date2) = ($0["date"], $1["date"])
if date1.timeIntervalSince1970 != date2.timeIntervalSince1970 {
return date1 > date2
}
// And lastly sort by time
return $0["time"] > $1["time"]
}

Sharepoint 2010 Blog - Order rest query by Category

I've created a blog on Sharepoint 2010 and want to query the list via REST for reporting. I want to order the list by the default field Category (internal name PostCategory). Unfortunately, this is a multiselect field, therefore a simple "?$orderby=Category" doesn't work. I've also tried to expand the Category, but that doesn't work either.
Is there a chance, that I can order the list using rest? What about more then one selected Category? Can it be ordered by the first category, then the second, etc.?
If it's not possible using REST, what about ordering within JSON? I use a small javascript, that puts the list in a reporting format. Can I order within the JSON result?
Here is an example:
// Create REST-API URL
var strURL = "<REST-URL>";
// Get information from REST-API and create html output
$.getJSON(strURL, function(data) {
<Create output>
};
// Append to webpart
$('#<WebPartTitle>').append($(html));
EDIT: I've posted the question also here, since it's happening all in sharepoint
Category field (PostCategory internal name) is a multiple choice field, in SharePoint REST it is not supported to apply $orderby query option to this type of field.
But you could sort returned items using JavaScript.
The following example demonstrates how to order Posts by Category field.
There is one important note here:
Since Category field is a multiple choice field value, it is
assumed that only one category could be specified per post.
For that purpose FirstCategoryTitle property is introduced which
represent the title of first category in post item. This property is used > for sorting items
Example
var endpointUrl = 'http://contoso.intranet.com/blog/_vti_bin/listdata.svc/Posts?$expand=Category';
$.getJSON(endpointUrl, function(data) {
var items = data.d.results.map(function(item){
item.FirstCategoryTitle = (item.Category.results.length > 0 ? item.Category.results[0].Title : ''); //get first category
return item;
});
items.sort(postComparer); //sort by category
items.forEach(function(item){
console.log(item.Title);
});
});
function postComparer(x,y) {
return x.FirstCategoryTitle > y.FirstCategoryTitle;
}

Complicated Laravel relationship to generate view

I have Orders which contain any number of items stored in the items table (so a belongsToMany relationship between the two). The items are also categorized under itemtypes. When creating or editing an order I would like to load all items, categorized by itemtype, whether or not that order has any of the items. I was able to pull that up generically using the following:
$itemtypes = \App\Itemtype::with('items')
->orderBy('id','asc')
->get();
Then I loop through:
#foreach( $itemtypes as $itemtype )
{{$itemtype->name}}
#foreach( $itemtype->items as $item )
{{$item->name}}
#endforeach
#endforeach
This gives me something like:
NICU Items
- Baby Blanket
- Beaded Baby Cuddler
Miscellaneous Items
- Fitted Sheet
- Microfiber Towel
However, when I'm accessing a specific order which has records in item_order I want to display the saved quantities (stored in the pivot table). I know one way would be to add records for all items to item_order for every order created but that seems rather inefficient.
Item.php
public function orders() {
return $this->belongsToMany('App\Order', 'item_order', 'item_id', 'order_id') -> withPivot('id','quantity','createdby_user_id','weight','cost_billed', 'calc_by_weight', 'track_units');
}
Order.php
public function items() {
return $this -> belongsToMany('App\Item', 'item_order', 'order_id', 'item_id') -> withPivot('id','quantity','quantity_received','quantity_delivered','notes', 'createdby_user_id', 'weight', 'cost_billed', 'calc_by_weight', 'track_units');
}
UPDATE
I'm on the trail to a solution. I'm converting the collection to an array, loaded up with all items, modifying the array as needed, then using array_merge to replace the items that have quantities already in item_order.
This all works great - the only issue I'm having now is that when I load the order with it's items, items have an itemtype - a categorization and I'd like to group them by that. I'm not sure how to add a groupby to a relationship. If I figure it all out i'll post the full answer then.