ترتيب الفئات باستخدام SQL

The following code changes the order of categories to be alphanumeric using SQL.

Preconditions.
Postgres backend

UPDATE categories
SET POSITION = subquery.position
FROM (
	SELECT POSITION
	, CASE WHEN category_id = 0 THEN parent_category_id ELSE category_id END category_id 
	, CASE WHEN category_id = 0 THEN parent_category_name ELSE category_name END category_name 
	FROM (
		SELECT ROW_NUMBER - 1 AS POSITION
		, parent_category_id
		, parent_category_name
		, category_id
		, category_name
		FROM ( SELECT row_number() OVER ( ORDER BY parent_category_name, category_name )
		, * FROM (
		SELECT * FROM (
			SELECT id parent_category_id
			, name parent_category_name 
			, 0 category_id
			, cast('' AS text) category_name
			FROM categories 
			WHERE parent_category_id IS NULL ORDER BY name
		) parent_categories
		UNION 
		(
			SELECT child.parent_category_id
			, parent.name parent_category_name 
			, child.id category_id
			, child.name category_name
			FROM categories child
			INNER JOIN categories parent
			ON child.parent_category_id = parent.id
			WHERE child.parent_category_id IS NOT NULL ORDER BY child.name
		) 
		) parents_with_children
		ORDER BY parent_category_name, category_name
		) ordered_parents_with_children
		ORDER BY ROW_NUMBER
	) category_positions_sorted_alphabetically
) subquery
WHERE id = subquery.category_id ;

I ran the code by starting up a psql session.

/var/discourse/launcher enter app
su postgres
psql discourse

and then executing the SQL.

Running from rails console.

ActiveRecord::Base.connection.execute("UPDATE categories SET POSITION = subquery.position FROM ( SELECT POSITION , CASE WHEN category_id = 0 THEN parent_category_id ELSE category_id END category_id , CASE WHEN category_id = 0 THEN parent_category_name ELSE category_name END category_name FROM ( SELECT ROW_NUMBER - 1 AS POSITION , parent_category_id , parent_category_name , category_id , category_name FROM ( SELECT row_number() OVER ( ORDER BY parent_category_name, category_name ) , * FROM ( SELECT * FROM ( SELECT id parent_category_id , name parent_category_name , 0 category_id , cast('' AS text) category_name FROM categories WHERE parent_category_id IS NULL ORDER BY name ) parent_categories UNION ( SELECT child.parent_category_id , parent.name parent_category_name , child.id category_id , child.name category_name FROM categories child INNER JOIN categories parent ON child.parent_category_id = parent.id WHERE child.parent_category_id IS NOT NULL ORDER BY child.name ) ) parents_with_children ORDER BY parent_category_name, category_name ) ordered_parents_with_children ORDER BY ROW_NUMBER ) category_positions_sorted_alphabetically ) subquery WHERE id = subquery.category_id")
إعجابَين (2)

I’ve not tested this recently but here’s at least a hint for how to alpha-sort categories at the rails console:

# alpha sort all categories matching search and their sub-categories

  def sort_matching_categories_and_subcategories(search)
    categories = Category.where("name like ?", search)
    position = 100
    categories.order(:name).each do |cat|
      position += 5
      cat.position = position
      cat.save!()
      c_position = 0
      children = Category.where(:parent_category_id=>cat.id)
      children.order(:name).each do |c|
        c_position += 5
        c.position = c_position
        c.save!()
      end
    end
  end


 # alpha sort subcategories of a single category matching search
def sort_matching_subcategories(search)
  categories = Category.where("name like ?", search)
  if categories.count > 1
    puts "Found more than one category"
  end
  categories.order(:name).each do |cat|
    c_position = 5
    children = Category.where(:parent_category_id=>cat.id)
    children.order(:name).each do |c|
      c_position += 5
      c.position = c_position
      c.save!()
    end
  end
end
إعجاب واحد (1)

Thanks @pfaffman

Based on your ruby code I came up with

def sort_categories_by_name(skip=0)
  
  parents = Category.where("parent_category_id is null")
  position = 0
  parents.order(:name).each do |parent|
    parent.position = position
    parent.save!()
    position += (1+skip)
    children = Category.where(:parent_category_id=>parent.id)
    children.order(:name).each do |child|
      child.position = position
      child.save!()
      position += (1+skip)  
    end
  end
  
  position += -(1+skip)  
  return position
  
end

sort_categories_by_name
إعجاب واحد (1)

مرحباً. هذه أول مرة لي هنا.
هل يوضح هذا المنشور أنه لا يمكن تعيين الفئات ترتيبياً عبر خيار واجهة مستخدم رسومية ما؟

شكراً لك

نوعًا ما. توجد إعدادات لوضعها بترتيب ثابت. أعتقد أنك أولاً تضبط إعدادًا للنظام (ابحث عن

شكرًا لك. أنا مجرد مستخدم في منتدى ‘ديسكورش’ منتدى فريبون، وقد طلبت من المشرفين تغيير الترتيب المذكور، لكن الرد الأول كان بالرجوع إلى هذا المنتدى لمعرفة كيفية القيام بذلك، مما يعني على الأرجح أن هذه ليست خيارًا متاحًا بسهولة كما أتخيل.

شكرًا مرة أخرى

ما لم تكن هناك عشرات الفئات، فلا يُعدّ الأمر مشكلة كبيرة. وإذا أحالوك إلى هنا بدلاً من أن يبحثوا في الإعدادات بأنفسهم أو يطرحوا سؤالهم هنا بأنفسهم، فهذا يعني ببساطة أنهم لا يرغبون في بذل الجهد اللازم.

شكرًا مرة أخرى.

أعتقد أن المشرفين ليس لديهم وصول إلى الخلفية، وهو ما يبدو ضروريًا.

أعتقد أنني سيقوم بتنزيل واستضافة واحد، وبالتالي يجب أن أتمكن من معرفة كيفية القيام بما أريده ونقل المعلومات :slight_smile: يجب أن يكون هناك مسؤول قادر على معالجة المشكلة.

إعجاب واحد (1)

يبدو أن أحد المشرفين يعرف كيفية القيام بذلك، وسأخبرك. الخبر هو أنه يمكن القيام بذلك عبر قائمة الهامبرغر ؟؟