精华内容
下载资源
问答
  • 在Wince6.0里面实现EDB数据库多字段排序一直没有新的进展,始终只能够实现一个字段的排序,不知道哪里出了问题,代码附上:按照设想,将 PINYIN_QUANPIN 作为主排序字段,MAINMOBILE作为辅助排序的字段 创建数据卷及...

    在Wince6.0里面实现EDB数据库多字段排序一直没有新的进展,始终只能够实现一个字段的排序,不知道哪里出了问题,代码附上:

    按照设想,将 PINYIN_QUANPIN 作为主排序字段,MAINMOBILE作为辅助排序的字段 创建数据卷及数据库:

     SORTORDERSPECEX dbSortInfo;
     dbSortInfo.wVersion = 2;
     dbSortInfo.wNumProps = 2;

     dbSortInfo.wKeyFlags = 0;
     dbSortInfo.rgPropID[0] =PINYIN_QUANPIN;
     dbSortInfo.rgdwFlags[0] = CEDB_SORT_CASEINSENSITIVE;

     dbSortInfo.rgPropID[1] = MAINMOBILE;
     dbSortInfo.rgdwFlags[1] = CEDB_SORT_CASEINSENSITIVE;
     if (!m_database.CreateDataBase(CEPropSpec, nFieldIndex, &dbSortInfo, 1))//将原来的dbSortInfo.wNumProps修改成1,因为参数排序的字段是一个而不是两个

     {
      MessageBox(L"创建数据库失败", L"ERROR", MB_OK);
      return ;
     }

     

    函数m_database.CreateDataBase 的实现如下:

    BOOL CDataBase::CreateDataBase(PCEPROPSPEC CEPropSpec, int nPropCount, SORTORDERSPECEX *pdbSortInfo, int ndbSortCount)
    {
     BOOL ret = FALSE;//, bExit = FALSE;
     if(m_szVolumName == NULL || m_szDbaseName== NULL)
      return FALSE;

     

     CEDBASEINFOEX info = {0};
     info.wVersion = 2;
     info.wNumSortOrder = ndbSortCount; //由参数传如应该参与排序创建数据库的字段

     info.dwFlags = (CEDB_VALIDNAME | CEDB_VALIDTYPE | CEDB_VALIDSORTSPEC);
     wcscpy(info.szDbaseName, m_szDbaseName);
     info.dwDbaseType = 0x777;
     info.dwSize = nPropCount; 
     info.dwNumRecords = 1500;

    /* for(int i=0; i < ndbSortCount; i++)
     {
      info.rgSortSpecs[0].rgPropID[i] = pdbSortInfo->rgPropID[i];
      info.rgSortSpecs[0].rgdwFlags[i] = pdbSortInfo->rgdwFlags[i];
      info.rgSortSpecs[0].wKeyFlags = pdbSortInfo->wKeyFlags;
      info.rgSortSpecs[0].wNumProps = pdbSortInfo->wNumProps;
      info.rgSortSpecs[0].wReserved = pdbSortInfo->wReserved;
      info.rgSortSpecs[0].wVersion = pdbSortInfo->wVersion;
     }*/

     

    //这样书写才是正确的,以上写法错误

     for(int i=0; i < ndbSortCount; i++)
     {
      info.rgSortSpecs[i] = pdbSortInfo[i];
     }

     

     ret = CeMountDBVolEx(&m_guid, m_szVolumName, NULL, CREATE_NEW);//CREATE_NEW
     int nError = GetLastError();
     if(nError == ERROR_ALREADY_EXISTS)//数据库卷存在
     {
      ret = CeMountDBVolEx(&m_guid, m_szVolumName, NULL, OPEN_ALWAYS);//OPEN_EXISTING
     }
     if(ret == FALSE)
     {
      RETAILMSG(1, (TEXT("CreateDataBase FAILED 2 nError=%d"), GetLastError() ));
      return FALSE;
     }

     if((m_oid = CeCreateDatabaseWithProps(&m_guid, &info, nPropCount, CEPropSpec)) == NULL)
     {
      nError = GetLastError();
      if(ERROR_DUP_NAME == nError)//数据库已经在卷中存在
      {
       CeUnmountDBVol(&m_guid);
       CREATE_SYSTEMGUID(&m_guid);
       m_oid = 0;
       m_hDataBaseHandle = NULL;
       SetLastError(0);
       return TRUE;
      }
      CeUnmountDBVol(&m_guid);
      CREATE_SYSTEMGUID(&m_guid);
      m_oid = 0;
      m_hDataBaseHandle = NULL;
      SetLastError(nError);
      RETAILMSG(1, (TEXT("CreateDataBase FAILED 3 nError=%d"), nError ));
      return FALSE;
     }

     CeUnmountDBVol(&m_guid);
     return TRUE;
    }

    此后,数据库卷以及数据库创建成功

    然后打开空的数据库,方式如下:

     SORTORDERSPECEX dbSortInfo;
     dbSortInfo.wVersion = 2;
     dbSortInfo.wNumProps = 2;
     dbSortInfo.wKeyFlags = 0; 
     dbSortInfo.rgPropID[0] = OPPO_PINYIN_QUANPIN;
     dbSortInfo.rgdwFlags[0] = CEDB_SORT_CASEINSENSITIVE;

     dbSortInfo.rgPropID[1] = OPPO_MAINMOBILE;
     dbSortInfo.rgdwFlags[1] = CEDB_SORT_CASEINSENSITIVE;

     if(!m_database.OpenDataBase(&dbSortInfo))
     {
      MessageBox(L"打开数据库失败", L"ERROR", MB_OK);
      return ;
     }
     return ;

     

    BOOL CDataBaseDll::OpenDataBase(SORTORDERSPECEX *pdbSortInfo)
    {
     BOOL ret = FALSE;
     int dwError = 0;
     if(m_szVolumName == NULL || m_szDbaseName== NULL)
      return FALSE;

     ret = CeMountDBVolEx(&m_guid, m_szVolumName, NULL, OPEN_ALWAYS);
     if(ret == FALSE)
     {
      RETAILMSG(1, (TEXT("OpenDataBase FAILED 1 nError=%d"), GetLastError()));
      return FALSE;
     }

     HANDLE hSession = CeCreateSession(&m_guid);
     CloseHandle(m_hDataBaseHandle);

     if((m_hDataBaseHandle = CeOpenDatabaseInSession(hSession, &m_guid, &m_oid, m_szDbaseName, pdbSortInfo, 0, NULL)) == INVALID_HANDLE_VALUE)
     {
      dwError = GetLastError();
      CeUnmountDBVol(&m_guid);
      CREATE_SYSTEMGUID(&m_guid);
      m_oid = 0;
      m_hDataBaseHandle = NULL;
      SetLastError(dwError);
      return FALSE;
     }

     return TRUE;
    }

     

    这样打开数据库也没有任何错误。

    然后就是一直让里面写入具体的纪录内容了。写完之后再用另一个应用程序以上面相同的方式打开数据库,可以看到内容是以PINYIN_QUANPIN字段进行排序读出来的。

    这个时候,我又想以MAINMOBILE字段进行查找某个字段,定位方式如下:

    CEPROPVAL CEpropval[2];

     CEpropval[0].propid = PINYIN_QUANPIN;
     CEpropval[0].val.lpwstr = L"";

    CEpropval[1].propid = MAINMOBILE;
    CEpropval[1].val.lpwstr = strSearch.GetBuffer();

     

    CEOID oid = theApp.m_Contact.SeekToValueGreater(CEpropval);

     while(oid)
     {
      theApp.m_Contact.ReadRecord();
      oid = theApp.m_Contact.SeekToNext();
     }

     

    这样的出的结果是以PINYIN_QUANPIN字段来进行数据定位,确实与MAINMOBILE字段输入参数无关。

     

     终于搞定了关于多个字段排序之后的一些查找算法了。

     

    展开全文
  • 应用场景:如果我们按排序且有升序和降序的时候的写法。 排序时,有两关键字 :asc 表示升序,desc 表示降序; 所以我们在order by 后面添加 asc, desc。 select s.bank_code,s.account_id,s.amount from...

    应用场景:如果我们按多列排序且有升序和降序的时候的写法。 

    排序时,有两个关键字 :asc  表示升序,desc 表示降序;

    所以我们在order by 后面添加 asc, desc。

    select s.bank_code,s.account_id,s.amount from Bp3_Bank_Account_Record s  order by 2 desc, 3 asc;
    

    这种写法,将Bp3_Bank_Account_Record该表的 account_id  字段 按降序排列,amount字段按照升序排列。 如果多个列也可以参考这种写法

    以下为截图:

    我们可以看到,按照第二列整体降序,按照第三列分区间升序排列。

     

    展开全文
  • 多个字段排序的时候,按照你在order by 之中指定的顺序进行排列的。 select * form tbl1 order by col1 desc, col2, col3 如上面, 先按照col1 的值递减排列, 如果col1的值相同,则按照col2来排列, 如果col1和...
    多个字段排序的时候,按照你在order by 之中指定的顺序进行排列的。
    select  * form tbl1 order by col1 desc, col2, col3
    如上面, 先按照col1 的值递减排列,
    如果col1的值相同,则按照col2来排列,
    如果col1和col2的值都相同,则按照col3的值进行排列。
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class SortTest {
    
    	static Map<String, Integer> sortNameMap = new HashMap<String, Integer>();
    	static {
    		sortNameMap.put("张三", 1);
    		sortNameMap.put("王五", 2);
    		sortNameMap.put("赵六", 3);
    		sortNameMap.put("李四", 4);
    	}
    
    	public static Integer getSortNameMapByKey(String key) {
    		for (String s : sortNameMap.keySet()) {
    			if (key.contains(s)) {
    				return sortNameMap.get(s);
    			}
    		}
    		return sortNameMap.size() + 1;
    	}
    
    	public static <T> void sort(List<T> list,
    			final List<Comparator<T>> comparatorList) {
    		if (comparatorList.isEmpty()) {// Always equals, if no Comparator.
    			throw new IllegalArgumentException("comparatorList is empty.");
    		}
    		Comparator<T> comparator = new Comparator<T>() {
    			public int compare(T o1, T o2) {
    				for (Comparator<T> c : comparatorList) {
    					if (c.compare(o1, o2) > 0) {
    						return 1;
    					} else if (c.compare(o1, o2) < 0) {
    						return -1;
    					}
    				}
    				return 0;
    			}
    		};
    		Collections.sort(list, comparator);
    	}
    
    	public static <E> void sortByMethod(List<E> list, final String method,
    			final boolean reverseFlag) {
    		Collections.sort(list, new Comparator<Object>() {
    			@SuppressWarnings("unchecked")
    			public int compare(Object arg1, Object arg2) {
    				int result = 0;
    				try {
    					Method m1 = ((E) arg1).getClass().getMethod(method, null);
    					Method m2 = ((E) arg2).getClass().getMethod(method, null);
    					Object obj1 = m1.invoke(((E) arg1), null);
    					Object obj2 = m2.invoke(((E) arg2), null);
    					if (obj1 instanceof String) {
    						if (method.toLowerCase().contains("name")) {
    							Integer sort1 = getSortNameMapByKey((String) (obj1));
    							Integer sort2 = getSortNameMapByKey((String) (obj2));
    							result = sort1.compareTo(sort2);
    						} else {
    							// 字符串
    							result = obj1.toString().compareTo(obj2.toString());
    						}
    					} else if (obj1 instanceof Date) {
    						// 日期
    						long l = ((Date) obj1).getTime()
    								- ((Date) obj2).getTime();
    						if (l > 0) {
    							result = 1;
    						} else if (l < 0) {
    							result = -1;
    						} else {
    							result = 0;
    						}
    					} else if (obj1 instanceof Integer) {
    						// 整型(Method的返回参数可以是int的,因为JDK1.5之后,Integer与int可以自动转换了)
    						result = (Integer) obj1 - (Integer) obj2;
    					} else {
    						// 目前尚不支持的对象,直接转换为String,然后比较,后果未知
    						result = obj1.toString().compareTo(obj2.toString());
    
    						System.err
    								.println("MySortList.sortByMethod方法接受到不可识别的对象类型,转换为字符串后比较返回...");
    					}
    
    					if (reverseFlag) {
    						// 倒序
    						result = -result;
    					}
    				} catch (NoSuchMethodException nsme) {
    					nsme.printStackTrace();
    				} catch (IllegalAccessException iae) {
    					iae.printStackTrace();
    				} catch (InvocationTargetException ite) {
    					ite.printStackTrace();
    				}
    
    				return result;
    			}
    		});
    	}
    
    	public static <E> int compareTo(Object arg1, Object arg2, String method,
    			boolean reverseFlag) {
    		int result = 0;
    		try {
    			Method m1 = ((E) arg1).getClass().getMethod(method, null);
    			Method m2 = ((E) arg2).getClass().getMethod(method, null);
    			Object obj1 = m1.invoke(((E) arg1), null);
    			Object obj2 = m2.invoke(((E) arg2), null);
    			if (obj1 instanceof String) {
    				if (method.toLowerCase().contains("name")) {
    					Integer sort1 = getSortNameMapByKey((String) (obj1));
    					Integer sort2 = getSortNameMapByKey((String) (obj2));
    					result = sort1.compareTo(sort2);
    				} else {
    					// 字符串
    					result = obj1.toString().compareTo(obj2.toString());
    				}
    			} else if (obj1 instanceof Date) {
    				// 日期
    				long l = ((Date) obj1).getTime() - ((Date) obj2).getTime();
    				if (l > 0) {
    					result = 1;
    				} else if (l < 0) {
    					result = -1;
    				} else {
    					result = 0;
    				}
    			} else if (obj1 instanceof Integer) {
    				// 整型(Method的返回参数可以是int的,因为JDK1.5之后,Integer与int可以自动转换了)
    				result = (Integer) obj1 - (Integer) obj2;
    			} else {
    				// 目前尚不支持的对象,直接转换为String,然后比较,后果未知
    				result = obj1.toString().compareTo(obj2.toString());
    
    				System.err
    						.println("MySortList.sortByMethod方法接受到不可识别的对象类型,转换为字符串后比较返回...");
    			}
    
    			if (reverseFlag) {
    				// 倒序
    				result = -result;
    			}
    		} catch (NoSuchMethodException nsme) {
    			nsme.printStackTrace();
    		} catch (IllegalAccessException iae) {
    			iae.printStackTrace();
    		} catch (InvocationTargetException ite) {
    			ite.printStackTrace();
    		}
    
    		return result;
    	}
    
    	public static <E> void sortByMethods(List<E> list,
    			final boolean reverseFlag, final String... methods) {
    		Collections.sort(list, new Comparator<Object>() {
    			@SuppressWarnings("unchecked")
    			public int compare(Object arg1, Object arg2) {
    				int result = 0;
    				for (String m : methods) {
    					result = compareTo(arg1, arg2, m, reverseFlag);
    					if (result != 0) {
    						return result;
    					} else {
    						result = compareTo(arg1, arg2, m, reverseFlag);
    					}
    				}
    
    				return result;
    			}
    		});
    	}
    
    	public static void main(String[] args) {
    		System.out.println("2".compareTo("1"));
    		List<Person> list = new ArrayList<Person>();
    		Person p = new Person();
    		p.setId(1);
    		p.setName("张三111");
    		list.add(p);
    		p = new Person();
    		p.setId(2);
    		p.setName("李四111");
    		list.add(p);
    		p = new Person();
    		p.setId(3);
    		p.setName("王五111");
    		list.add(p);
    		
    		p = new Person();
    		p.setId(4);
    		p.setName("王五111");
    		list.add(p);
    		
    		p = new Person();
    		p.setId(40);
    		p.setName("赵六1111");
    		list.add(p);
    		
    		p = new Person();
    		p.setId(5);
    		p.setName("赵六1111");
    		list.add(p);
    		
    		p = new Person();
    		p.setId(5);
    		p.setName("小王1111");
    		list.add(p);
    		p = new Person();
    		p.setId(6);
    		p.setName("老王1111");
    		list.add(p);
    
    		sortByMethods(list, false, "getName","getId");
    		System.out.println("中文名称正序排列:");
    		for (Person pp : list) {
    			System.out.println(pp.getId() + "," + pp.getName());
    		}
    
    		/*
    		 * sortByMethod(list, "getName", false);
    		 * System.out.println("中文名称正序排列:"); for (Person pp : list) {
    		 * System.out.println(pp.getId() + "," + pp.getName()); }
    		 * 
    		 * sortByMethod(list, "getId", false); System.out.println("中文名称正序排列:");
    		 * for (Person pp : list) { System.out.println(pp.getId() + "," +
    		 * pp.getName()); }
    		 */
    
    	}
    
    }
    
    class Person {
    	private int id;
    	private String name;
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public int getId() {
    		return id;
    	}
    
    	public void setId(int id) {
    		this.id = id;
    	}
    
    }

     

    展开全文
  • php array_multisort对数据库结果多个字段进行排序$data 数组中的每个单元表示一个表中的一行。这是典型的数据库记录的数据集合。 例子中的数据如下:volume | edition -------+-------- 67 | 2 86 | 1 85 | 6 98 | ...

    php array_multisort对数据库结果多个字段进行排序
    $data 数组中的每个单元表示一个表中的一行。这是典型的数据库记录的数据集合。
    例子中的数据如下:
    volume | edition -------+-------- 67 | 2 86 | 1 85 | 6 98 | 2 86 | 6 67 | 7
    数据全都存放在名为 data 的数组中。这通常是通过循环从数据库取得的结果,例如 mysql_fetch_assoc()。
    <?php
    $data[] = array('volume' => 67, 'edition' => 2);
    $data[] = array('volume' => 86, 'edition' => 1);
    $data[] = array('volume' => 85, 'edition' => 6);
    $data[] = array('volume' => 98, 'edition' => 2);
    $data[] = array('volume' => 86, 'edition' => 6);
    $data[] = array('volume' => 67, 'edition' => 7);
    ?>

    本例中将把 volume 降序排列,把 edition 升序排列。
    现在有了包含有行的数组,但是 array_multisort() 需要一个包含列的数组,因此用以下代码来取得列,然后排序。
    <?php
    // 取得列的列表
    foreach ($data as $key => $row) {
    $volume[$key] = $row['volume'];
    $edition[$key] = $row['edition'];
    }
    // 将数据根据 volume 降序排列,根据 edition 升序排列
    // 把 $data 作为最后一个参数,以通用键排序
    array_multisort($volume, SORT_DESC, $edition, SORT_ASC, $data);
    ?>
    数据集合现在排好序了,结果如下:
    volume | edition -------+-------- 98 | 2 86 | 1 86 | 6 85 | 6 67 | 2 67 | 7

    ====================================================
    实例2:
    //有优惠活动优先 + 上架时间 最新时间的在最上面
    //根据商品id取出来然后在用数组排序array_multisort
    foreach ($goods as $key => $row) {
    $start_time[$key] = $row['goods_listing_start_time'];
    $is_activity[$key] = $row['is_activity'];
    }
    //SORT_ASC SORT_DESC
    array_multisort($is_activity,SORT_DESC,$start_time, SORT_DESC, $goods);

    展开全文
  • mysql 多个字段排序

    2021-04-08 10:55:43
    mysql order by 多个字段排序 工作中需用到order by 后两个字段排序,但结果却产生了一个Bug,以此备录。 【1】复现问题场景 为了说明问题,模拟示例数据库表students,效果同实例。 如下语句Sql_1: SELECT * FROM ...
  • mysql order by 多个字段排序

    万次阅读 2020-08-27 12:07:22
    工作中需用到order by后两个字段排序,但结果却产生了一个Bug,以此备录。 【1】复现问题场景 为了说明问题,模拟示例数据库表students,效果同实例。 如下语句Sql_1: 1 SELECT * FROM students st ORDER BY ...
  • sqlserver的order by多个字段排序优先级

    千次阅读 2019-07-12 17:03:54
    环境:SQLserver2012,数据库比较lower 不要介意, 首先简单的来, 1:单个字段排序 SELECT * FROM dbo.app_merchant_card_limit ORDER BY added_time desc 结果如图 ...2:多个字段排序 SELECT * FRO...
  • 按照多个字段排序查询结果 需求描述 需求:从雇员表emp里查询所有的部门编号,员工名称,职位,工资信息,这里要求先以部门编号排序再以工资从高到低排序显示。 解决方法:这里用到SQL的关键字 ORDER BY 以及ASC和...
  • 解决Mysql数据库实现表联合查询并按照其中一个字段进行排序问题
  • 本人比较新手,现在前端一个表格由多个数据库表的字段查询组成,包括统计字段,现在要使用一个sql实现通过该表格所有字段来做排序和过滤,sql怎么写![图片说明]...
  • 为了提升工程性能,尽量减少数据库的连接,这时候...多字段排序,第一排序,第二排序 select a.* ,b.* from table_a a,table_b b order by a.id,b.id 也就是先按照table_a id排序,当相同的时候,再按照b.id排序...
  • mysql多字段排序

    2020-07-02 22:41:51
    数据库可以对多个字段进行排序,优先级顺序按照书写顺序 说明: 对于多字段排序是这个样子的 初始数据如下,观察c1字段中相同的数据: 观察上图,对于单一字段来说,可以进行排序 如下图,再增加一个字段c2,进行多...
  • 混合排序有很种情况,太复杂的我目前也没遇到过,这次在项目中遇到的是一个有规律的字段,这个字段的值都是以#开头的,下面说一下我的方法: ORDER BY CAST(substring_index(name,'#',1) AS SIGNED) asc 如上所示...
  • //需要排序的数组,可以按多个键名排序 $array = array( 0 =&gt; array('name'=&gt;'a','value'=&gt;2,'order'=&gt;5), 1 =&gt; array('name'=&gt;'b','value'=&gt;4,'order'=&...
  • 使用场景: 在使用mysql数据库中,假如同时插入多条数据,即这些数据的创建时间都是一致的。此时如果单单使用创建时间来排序,会遇到:因为某几条记录创建时间一致时,所以每次请求...mysql多个字段排序: select...
  • 数据库是集合操作,所以有时候为了表示顺序可能会加一个字段用于保存顺序,我看我周边的程序员天然的选择整数作为顺序号,我一开始也这么做,后来发现问题很严重,例如有100条记录,顺序为1,2..100,如果在第二条记录...
  • array_multisort()对多维数组进行排序,这功能在做项目的时候是有时会很有用的!...相当于数据库查询是order by多字段排序。 //待排序数组 $arr_data = array( array('id'=>1,'name'=>'D','money'=>10)
  • 工作中需用到order by后两个字段排序,但结果却产生了一个Bug,以此备录。 【1】复现问题场景 为了说明问题,模拟示例数据库表students,效果同实例。 如下语句Sql_1: 1 SELECT * FROM students st ORDER BY ...
  • 研究了一下系统的数据库结构后,决定将要排除到后面的产品加为粗体,这样在数据库中的“ifbold”就会被标记为1,而其他产品就默认标记为0,然后就打算使用MySQL在Order By时进行多字段排序。 Order by的条件分割...
  • 1.数据库联表查询,用第二张表的独有字段排序时,乱序 SELECT id, name, type, cts.hot FROM CT ct LEFT JOIN CTS cts ON cts.topic_id = ct.id ORDER BY cts.hot ASC 当排序的条件一样时,为何会以此种...
  • 这里面没有其他其他其他,然后客户在收货地址前写了很多个其他,导致了明明需要运费的,被这个聪明的客户占了便宜。变成了没有运费了!!!这是个bug!!!也不知道存在多久了。 修复过程:以为这样拼接了就能出来...
  • 多字段排序 -- PHP版

    2019-09-20 13:22:28
    闲来有空,说一下自己写的一个多字段排序算法。 之前有一需求是每日更新游戏排行榜,需要把近7天新增的游戏评价集合,计算平均分,按平均分倒序排列,平均分相等的按照游戏发行时间倒序来排。 数据库设计的时候是...
  • * 在数据库中查出来的列表中,往往需要对不同的字段重新排序。 一般的做法都是使用排序字段,重新到数据库中查询。 * 如果不到数据库查询,直接在第一次查出来的list中排序,无疑会提高系统的性能。 下面就写一...
  • 数据库多维度order by 排序分析

    千次阅读 2018-08-15 09:24:03
    商品信息中包含商品信息、发布时间、发货地点,取货方式等多个字段,现有需求:展示信息优先将同城且支持上门的需求按最新发布时间排序 其次显示同城支持快递的,然后是不同城支持快递的,最后是不同城且不支持快递...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,722
精华内容 688
关键字:

数据库多个字段排序