【问题标题】:Fetch records in order of ids provided and those ids which are not provided should index after these in alphabetic order按提供的 id 顺序获取记录,未提供的 id 应按字母顺序在这些后索引
【发布时间】:2015-08-21 13:11:18
【问题描述】:

我遇到了一个问题,即我有某些 id 需要首先在结果中编制索引,以便它们排列(在数组中)和其他记录按字母顺序获取但要显示在它们之后。

例如下面提到我的sql查询:

SELECT *
FROM `users` `t`
ORDER BY field( `t`.`id` , 3694181860160, 3690073978560, 3692021760768, 3696518283776, 3694455712256, 3698627050368, 3694698638592, 3696980086784, 3693461701760 )

它应该按顺序提供记录(3694181860160,369007396076,369651828376,36944557606,369862705038,36986980303,36946980398,369469803039,669698050384,369698008692,369698008678,369698008678,3693461701760)首先和所有其余的记录应按字母顺序显示。

目前我正在从提到的列表中获取记录,但顺序是随机的,其余记录不确定它们是如何排序的。

我也尝试使用

获取结果

order by find_in_set 但它也不起作用。

请帮忙。

以下是我的表结构:

 `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `fname` varchar(30) NOT NULL,
  `lname` varchar(30) NOT NULL,
  `email` varchar(50) NOT NULL,
  `password` varchar(100) DEFAULT NULL,
  `display_picture` varchar(255) DEFAULT NULL,
  `last_login` datetime NOT NULL,
  `reg_date` datetime NOT NULL,
  `user_type` enum('admin','user') NOT NULL DEFAULT 'user',
  `status` enum('0','1') NOT NULL DEFAULT '1',
  `email_verified` enum('0','1') NOT NULL DEFAULT '0',
  `feed_visibility` enum('public','relation','private') NOT NULL DEFAULT 'relation',
  `groups` text NOT NULL,
  `contact_allowance` enum('public','private','relation') NOT NULL DEFAULT 'public',
  `search_allowance` enum('0','1') NOT NULL DEFAULT '1',
  `country` int(11) NOT NULL,
  `dob` date NOT NULL,
  `gender` enum('male','female') DEFAULT NULL,
  `fb_id` varchar(50) NOT NULL,
  `state` varchar(255) NOT NULL,
  `city` varchar(255) NOT NULL,
  `street` varchar(255) NOT NULL,
  `is_admin` tinyint(1) NOT NULL DEFAULT '0',
  `flame_name` varchar(50) NOT NULL,
  `device_id` varchar(100) DEFAULT NULL,
  `fav_cat` text,
  `credits` int(20) DEFAULT NULL,
  `privacy_setting` varchar(255) DEFAULT NULL,
  `is_deleted` tinyint(4) NOT NULL DEFAULT '0',
  `reason_to_delete_account` varchar(255) NOT NULL,
  `verification_hash` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `email` (`email`)

除了提到的 id,如果它们不为空,我希望其余的记录按 fname 和 lname 排序。

我还要提一下,括号中的 ID 是从另一个表中获取的。

我想我还应该提到我正在尝试获取用户的排名。计算用户排名并将其记录在 Mongo db 中的单独表中。而'users'表保存了MySql中所有用户的记录。 很难描述排名的表结构。但是我们从排名表中获取 user_id 和 rank 字段。

我正在获取用户 ID,他们从排名表中获得排名,并尝试从用户表中获取用户信息,以便在所有用户都显示排名的页面中显示它们。其中很少有用户没有达到排名,所以他们的ID还没有在排名表中。我想按 fname、lname 的字母顺序对它们进行排序(如果它们有 fname、lname)

…………

我确实重新考虑过它,只返回那些由排名表获取的记录。因此,当排名表中有更多记录可用时,页面将显示更多记录。我使用查询作为

    SELECT * FROM `users` `t` where `t`.`id` in (3694181860160, 3690073978560, 3692021760768, 3696518283776, 3694455712256, 3698627050368, 3694698638592, 3696980086784, 3693461701760 )
ORDER BY field( `t`.`id` , 3694181860160, 3690073978560, 3692021760768, 3696518283776, 3694455712256, 3698627050368, 3694698638592, 3696980086784, 3693461701760 ) ASC

它运行良好,随着时间的推移,它会显示越来越多的用户。

【问题讨论】:

  • 请提供表格的结构。您尝试排序的另一个字段是什么?
  • @Ali 我链接你提到的对我没有用,因为我提到的括号中的值不是静态的,它会随着时间的推移而增长,并随着用户排名的波动而不断变化。

标签: mysql


【解决方案1】:

我认为这应该可以解决问题:

SELECT *
FROM `users` `t`
ORDER BY field( `t`.`id` , 3694181860160, 3690073978560, 3692021760768, 3696518283776, 3694455712256, 3698627050368, 3694698638592, 3696980086784, 3693461701760 ) DESC, `t`.`id` ASC;

如果您需要指定 ID 的顺序与输入的顺序相同,那么您必须单独选择每个 ID,然后将所有结果合并在一起。

【讨论】:

  • 我正在以这种方式获取记录。由于篇幅不足,发帖时间较短。此方法无效。["3696980086784","3694698638592","3698627050368","3694455712256","3696518283776","3692021760768","3694181860160","3699651556928","3692701454400","3698600774656","3694185651456","3693845934656","3693594951616","3691028107200","3691373773376","3697095829184","3690766807168","3692501641984","3698855465792","3699391648768","3697583058176","3696726122496","3693843354368","3693046966528","3697718637760","3691835711424","3698454857408","3692364783936","3696155633984","3697502467584"].
【解决方案2】:

也许您需要重新考虑您要对查询执行的操作。保证返回记录顺序的唯一方法是使用 and order-by 子句,但您的表中似乎没有可以排序的字段。据我了解,您希望返回值的任意顺序是在接近触发查询的时间决定的,并且无法提前知道(即运行时)。

所以你有两个选择:

  • 向表中添加数字排序字段,设置字段值以匹配您希望返回数据的确切顺序,然后立即查询表并按排序字段排序。
  • 查询数据,然后自己(在数据库之外)对记录进行排序,将列表中的每个项目准确地放在您想要的位置。

【讨论】:

    【解决方案3】:

    您应该有两个级别的ORDER BY。首先按您的首选值排序,然后按其余值排序。 9999 只是一个足够高的值,以确保非首选数字仅出现在首选数字之后:

    SELECT * FROM users t
    ORDER BY if(@x:=FIND_IN_SET(t.id,'3694181860160, 3690073978560, 3692021760768, 3696518283776, 3694455712256, 3698627050368, 3694698638592, 3696980086784, 3693461701760'),@x,9999), fname, lname;
    

    你也可以重写这个,这样你就不需要临时变量了:

    SELECT * FROM users t
    ORDER BY 
     IF(
      t.id IN (3694181860160, 3690073978560, 3692021760768, 3696518283776, 3694455712256, 3698627050368, 3694698638592, 3696980086784, 3693461701760), 
      FIND_IN_SET(t.id,'3694181860160, 3690073978560, 3692021760768, 3696518283776, 3694455712256, 3698627050368, 3694698638592, 3696980086784, 3693461701760'),
      9999), 
     fname, lname;
    

    在这种情况下,缺点是您需要提供两次首选 ID 列表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-12
      相关资源
      最近更新 更多