I want to sort data in repository based on the content of a specific field
For example i have an entity person with the fields role,fistName and lastName.
I would like to sort using ->orderBy('p.role', ???) and get a list ordered based on this order : professors then directors then teachers and at last students .
Example of my database:
Wanted result:
Ps: i can not use ASC or DESC since my sorting order is neither ASC nor DESC;
it is a custom order
Very strage scenario, you could use a CASE statement in order to assing a custom value for each fields then sort on him.
You could use the HIDDEN keyword.
As example take a look at this DQL:
SELECT p, CASE
WHEN p.role = "professor" THEN 1
WHEN p.role = "director" THEN 2
WHEN p.role = "teacher" THEN 3
WHEN p.role = "student" THEN 4
ELSE 99 END
AS HIDDEN mySortRule
FROM Bundle\Entity\Person p
ORDER BY mySortRule ASC
Hope this help
Related
I'm sorry for the confusing title, but couldn't find another way to ask it.
Let's say I want to write a procedure add_salesline. I enter all the fields with parameters, except subtotal. Subtotal (just the price for the salesline) needs to be calculated based on fields in other tables such as productprice in the table products, pricereduction in the table promotion, etc. (based on the properties).
How can I do this? I've been trying to solve this problem for a good week now, and it's just not working...
Presumably one of the parameters passed to procedure add_salesline() is productid, or whatever. So you use that to SELECT products.productprice, promotion.pricereduction and whatever else you need to perform the calculation.
The purpose of writing a stored procedure is to associate several calls into a single program unit. So add_salesline() might look something like this (lots of caveats because your question is very light on details):
create or replace procedure add_salesline(
p_orderno in salesline.orderno%type
, p_salesqty in salesline.salesqty%type
, p_productid in products.productid%type
)
is
new_rec salesline%rowtype;
begin
new_rec.orderno := p_orderno;
new_rec.salesqty := p_salesqty;
new_rec.productid := p_productid;
select p_salesqty * (p.productprice * nvl(pp.pricereduction, 1))
into new_rec.subtotal
from products p
left outer join promotion pp
on pp.productid = p.productid
where p.productid = p_productid
;
insert into salesline
value new_rec;
end;
This code assumes pricereduction is a rate. If the value is an absolute discount the formula will be different (p.productprice - nvl(pp.pricereduction, 0)). Or if it's a replacement price: coalesce(pp.pricereduction, p.productprice).
I have a product page on a webpage that shows categories of products. This is done with a listview populated from a database. The issue that I have is that the main supplier has demanded that their products are first in the category list. So what I need to do is run a query that will return the results, display those two categories first and then display the rest alphabetically.
So I've been trying to do this using a UNION ALL query like this:
SELECT cat, cat_id, image FROM prod_categories WHERE cat_id = 19 OR cat_id = 65
UNION ALL
SELECT cat, cat_id, image FROM prod_categories WHERE cat_id <> 19 AND cat_id <> 65
I thought with a union like this it would display the results of the first select query first, but it's not doing that.
I can add an 'order by cat' clause on the end, but obviously that only displays them in the correct order if the two categories I want to display come first alphabetically, which they don't.
If anyone has any ideas how to do this it would be greatly appreciated.
Thanks
How about this:
SELECT cat, cat_id, image FROM prod_categories
order by case when cat_id in (19, 65) then 1 else 2 end, cat_id
Cuts out the need to UNION altogether. Might even produce a more efficient execution plan (possibly...).
(using Transact-SQL for SQL Server - the exact syntax may have to be tinkered for MySql etc)
Try something like this.
SELECT cat, cat_id, image, 1 as [srt]
FROM prod_categories WHERE cat_id = 19 OR cat_id = 65
UNION ALL
SELECT cat, cat_id, image, 2 as [srt]
FROM prod_categories WHERE cat_id <> 19 AND cat_id <> 65
ORDER BY srt ASC, cat_id
Don't hard-code this into your query. What happens when the next supplier wants to come second? Or last? For that matter, you may want to list categories in some sort of "group", anyways.
Instead, you should be using an ordering table (or multiple). Something simple to get you started:
CREATE TABLE Category_Order (categoryId INTEGER -- fk to category.id, unique
priority INTEGER) -- when to display category
Then you want to insert the values for the current "special" categories:
INSERT INTO Category_Order (categoryId, priority) VALUES (19, 2147483647), (65, 0)
You'll also need an entry for rows that are not currently prioritized:
INSERT INTO Category_Order (categoryId, priority)
SELECT catId, -2147483648
FROM prod_categories
WHERE catID NOT IN (19, 65)
Which can then be queried like this:
SELECT cat, cat_id, image
FROM prod_categories
JOIN Category_Order
ON category_id = cat_id
ORDER BY priority DESC, cat
If you write a small maintenance program for this table, you can then push re-ordering duties off onto the correct business department. Reordering of entries can be accomplished by splitting the difference between existing entries, although you'll want a procedure to re-distribute if things get too crowded.
Note that, in the event your db supports a clause like ORDER BY priority NULLS LAST, the entries for non-prioritized categories are unnecessary, and you can simply LEFT JOIN to the ordering table.
The question probably is quite confusing.
In affect i have the following:
WatchList table
UserId | FilmId
| 3 77
| etc etc
|
|
|
these are foreign keys for the following tables
FilmDB - Film_title, Film_plot, Film_Id etc.
and
aspnet_memberships - UserId, Username etc..
Now, i presume i will need to use a join but i am struggling with the syntax.
I would like to use 'Count' on the 'WatchList' and return the most frequent filmId's and their counterpart information, but i'd then like to return the REST of the FilmDB results, essentially giving me a list of ALL films, but with those found in the WatchedList my frequently sorted to the top.
Does that make sense? Thanks.
SELECT *
FROM filmdb
LEFT JOIN (
SELECT filmid, count(*) AS cnt
FROM watch_list
GROUP BY filmid) AS a
ON filmdb.film_id = a.filmid
ORDER BY isnull(cnt, 0) DESC;
http://sqlfiddle.com/#!3/46b16/10
You did not specify if the query should be grouped by film_id or user_id. The example I have provided is grouped by user if you change that to film_id then you will get the watch count for all users per film.
You need to use a subquery to get the count and then order the results by the count descending to get an ordered list.
SELECT
*
FROM
(
SELECT
WatchList.Film_Id,
WatchCount=COUNT(*)
FilmDB.Film_Title
FROM
WatchList
INNER JOIN FilmDB ON FilmDB.Film_Id=WatchList.Film_Id
GROUP BY
WatchList.UserID,
WatchList.Film_Id,
FilmDB.Film_Title
)AS X
ORDER BY
WatchCount DESC
I have a MySQL table Page with 2 columns: PageID and OrderByMethod.
I also then have a Data table with lots of columns including PageID (the Page the data is on), DataName, and DataDate.
I want OrderByMethod to have one of three entries: Most Recent Data First, Most Recent Data Last, and Alphabetically.
Is there a way for me to tack an "ORDER BY" clause to the end of this query that will vary its ordering method based on the contents of the "OrderByMethod" column? For example, in this query, I would want to have the ORDER BY clause contain whatever ordering rule is stored in Page 1's OrderByMethod column.
GET * FROM `Data` WHERE `Data`.`PageID`=1 ORDER BY xxxxxx;
Maybe a SELECT clause in the ORDER BY clause? I'm not sure how that would work though.
Thanks!
select Data.*
from Data
inner join Page on (Data.PageID=Page.PageID)
where Data.PageID=1
order by
if(Page.OrderByMethod='Most Recent Data First', now()-DataDate,
if(Page.OrderByMethod='Most Recent Data Last', DataDate-now(), DataName)
);
You can probably do this with the IF syntax to generate a column that you can then order by.
SELECT *, IF(Page.OrderBy = 'Alphabetically', Data.DataName, IF(Page.OrderBy = 'Most Recent Data First', NOW() - Data.DataDate, Data.DataDate - NOW())) AS OrderColumn
FROM Data
INNER JOIN Page ON Data.PageID = Page.PageID
WHERE Page.PageID = 1
ORDER BY OrderColumn
The direction of the ordering is determined in the calculation of the data instead of specifying a direction in the ORDER BY
Can you just append the order by clause to the select statement and rebind the table on postback?
If you want to use the content of the column in Page table as an expression in ORDER BY you have to do it using prepared statements. Let say, you store in OrderByMethod something like "field1 DESC, field2 ASC" and you want this string to be used as it is:
SET #order_by =(SELECT OrderByMethod FROM Page WHERE id = [value]);
SET #qr = CONCAT(your original query,' ORDER BY ', #order_by);
PREPARE stmt FROM #qr;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
If you want the result set to be sorted based on the value of OrderByMethod , you can use IF as it was already mentioned by others, or CASE :
...
ORDER BY
CASE OrderByMethod
WHEN 'val1' THEN field_name1
WHEN 'val2' THEN field_name2
....etc
END
I have a custom content type which has a field called "location" which is a long select list (100 or so items). I want to get an array of all locations which have a piece of content associated with them. The numeric value of this field is stored in content_type_[my_content_type], but I can't find anywhere in the database where the name of the values are stored. I hope that's not too confusing - just to be clear, I want to do something like this:
SELECT DISTINCT(field_location_value) FROM content_type_[my_content_type]
and then
SELECT field_location_name_or_something FROM where_on_earth_are_the_names_stored
and then do something with the two arrays to find the names I want.
Can anyone help?
Thanks a lot. Drupal 6, by the way.
If you mean select list field of CCK:
Get all location associated with current node (piece of content?):
$node = node_load('YOUR content ID');
print_r($node->field_location); // $node->field_location - this will array of values.
Get all values of that field (defined in "Allowed values"):
$content_field = content_fields('field_location');
$allowed_values = content_allowed_values($content_field); // array of values
I found this, after much trial and tribulation, in the database table content_node_field_instance, under the field's widget settings field.
This Drupal 6 code snipped will retrieve your cck field value options and put them in the $allowed_values variable as an array. Replace 'YOUR_CCK_FIELD_NAME' with your cck field name (name, not label)
$cck_field_name = 'YOUR_CCK_FIELD_NAME';
$cck_field = db_fetch_object(db_query("SELECT global_settings FROM {content_node_field} WHERE field_name = '%s'", $cck_field_name));
$cck_field_global_settings = unserialize($cck_field->global_settings);
$allowed_values = explode("\r\n", trim($cck_field_global_settings['allowed_values'], "\r\n"));
In Drupal 7 if you have a field of type List (text) then I have written the following function to return an array of options:
function get_drupal_select_options($field_name) {
$options = unserialize(db_query("SELECT c.data
FROM field_config_instance i
INNER JOIN field_config c ON c.id = i.field_id
WHERE i.field_name = :fieldname", array(':fieldname'=>$field_name))->fetchField());
return $options['settings']['allowed_values'];
}