FIND_IN_SET如何按实际顺序输出

本文详细介绍了如何解决使用find_in_set()函数时遇到的排序问题,通过结合group_concat()函数实现按指定顺序输出查询结果的方法。包括SQL语句的构建与解释,以及对数据库查询机制的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

FIND_IN_SET是一个用来在数据库中进行字符串匹配的函数,之前我已经在博客中有详细描述。今天想和大家说说的是FIND_IN_SET()函数碰到的一个排序问题。

以我在项目中的实际情况为例:

数据描述:

user_id:( 4,3,1)  对应的user_name('test4','test3','test1')

场景:

给一个ID串“4,3,1” 不同ID用逗号隔开 

要求根据这个ID串得到姓名串“test4,test3,test1”

SQL语句:

select group_concat(user_name)

from user

where find_in_set(user_id,'4,3,1')

得到的结果  "test1,test3,test4"

为什么呢 这里就和数据库的查询机制有关,对于find_in_set()函数而言,数据库执行的是全表查询 而数据库默认是按ID索引进行排序的 这就导致有些字段排在后面但因为ID小而导致在结果中出现在前面。那么我们就想,可不可以让查询结果按我们输入的ID串中的顺序输出呢

这时find_in_set()函数又出来了  find_in_set()函数会根据逗号隔开的不同字段的先后给出对应的位置ID 这样办法就出来了。

select group_concat(user_name)

from user

where find_in_set(user_id,'4,3,1')

order by find_in_set(user_id,'4,3,1')

可得到的结果还是  "test1,test3,test4"


这是为什么呢  原因就在group_concat()这个函数  这个函数又会进行一次全表查询 然后ID小的字段又靠前了 这样 我们再改一次 加个外套给它

select group_concat(user_name)

 from (

select  user_name

from user

where find_in_set(user_id,'4,3,1')

order by find_in_set(user_id,'4,3,1')

) as temp

这样就通过一个临时表的外套 给他重新按我们排序好的进行二次查询就可以得到我们要的结果了。

<think>我们正在讨论CMake中的变量`CMAKE_CURRENT_LIST_FILE`。根据CMake官方文档,这个变量表示当前正在处理的CMake列表文件的完整路径。这里的“列表文件”通常指的是CMake脚本文件,例如`CMakeLists.txt`或通过`include()`命令包含的`.cmake`脚本文件。 ### 变量含义 - `CMAKE_CURRENT_LIST_FILE`:包含当前正在处理的CMake列表文件的完整路径(包括文件名)。这个变量会在处理不同的列表文件时动态改变。 ### 路径确定 - 当CMake处理一个项目时,它会从顶层的`CMakeLists.txt`开始执行。 - 当遇到`include()`命令或`add_subdirectory()`命令时,CMake会进入新的列表文件(即被包含的脚本文件或子目录中的`CMakeLists.txt`)。 - 在处理这些文件的过程中,`CMAKE_CURRENT_LIST_FILE`会更新为当前文件的完整路径。 - 一旦处理完该文件,返回到包含它的文件时,`CMAKE_CURRENT_LIST_FILE`会恢复为之前的值(即包含该文件的路径)。 ### 示例说明 假设我们有如下项目结构: ``` project/ ├── CMakeLists.txt └── subdir/ ├── CMakeLists.txt └── included.cmake ``` 在顶层`CMakeLists.txt`中: ```cmake cmake_minimum_required(VERSION 3.10) project(Example) message("Top: CMAKE_CURRENT_LIST_FILE = ${CMAKE_CURRENT_LIST_FILE}") # 输出顶层CMakeLists.txt的路径 include(subdir/included.cmake) # 包含一个脚本文件 add_subdirectory(subdir) # 添加子目录 ``` 在`subdir/included.cmake`中: ```cmake message("In included.cmake: CMAKE_CURRENT_LIST_FILE = ${CMAKE_CURRENT_LIST_FILE}") # 输出该脚本的路径 ``` 在`subdir/CMakeLists.txt`中: ```cmake message("In subdir: CMAKE_CURRENT_LIST_FILE = ${CMAKE_CURRENT_LIST_FILE}") # 输出子目录中CMakeLists.txt的路径 ``` 运行CMake时,输出顺序可能如下: 1. 顶层`CMakeLists.txt`中的消息,显示顶层文件的路径。 2. 在包含`included.cmake`时,输出该脚本的路径。 3. 在进入子目录`subdir`后,输出子目录中`CMakeLists.txt`的路径。 ### 作用 - 调试:在复杂的项目中,可以通过这个变量来追踪当前正在处理的文件,帮助调试CMake脚本。 - 路径相关操作:在编写可重用的CMake脚本时,可以根据当前文件的路径来定位相关资源(如同目录下的其他文件)。 ### 注意事项 - 该变量是只读的,不能修改。 - 与`CMAKE_CURRENT_SOURCE_DIR`不同,后者是当前处理的CMake列表文件所在的目录(不包括文件名),而`CMAKE_CURRENT_LIST_FILE`包含文件名。 ### 引用说明 根据用户提供的引用[^2]中关于`CMAKE_CURRENT_SOURCE_DIR`的说明(它指的是当前处理的CMake列表文件所在的目录),我们可以类比理解`CMAKE_CURRENT_LIST_FILE`:它不仅包含目录,还包含文件名。 §§相关问题§§ 1. `CMAKE_CURRENT_LIST_FILE`和`CMAKE_CURRENT_SOURCE_DIR`有什么区别? 2. 如何在CMake脚本中获取当前文件所在的目录? 3. 在CMake中,如何根据当前脚本的位置来包含其他文件?</think>### CMAKE_CURRENT_LIST_FILE 详解 在 CMake 中,`CMAKE_CURRENT_LIST_FILE` 是一个**自动更新的只读变量**,用于表示当前正在处理的 CMake 列表文件的完整路径。以下是其核心特性和作用: #### 1. **路径来源与确定** - **来源**:当 CMake 处理任何列表文件(如 `CMakeLists.txt` 或通过 `include()` 加载的 `.cmake` 脚本)时,该变量会自动更新为当前文件的绝对路径。 - **路径组成**: `CMAKE_CURRENT_LIST_FILE = <当前处理的文件完整路径>` 例如:`/project/src/module/CMakeLists.txt` #### 2. **与相关变量的区别** | 变量名 | 含义 | 示例 | |--------|------|------| | `CMAKE_CURRENT_LIST_FILE` | **当前处理的列表文件完整路径** | `/project/src/CMakeLists.txt` | | `CMAKE_CURRENT_SOURCE_DIR` | 当前列表文件所在目录 | `/project/src` | | `CMAKE_SOURCE_DIR` | 顶层 `CMakeLists.txt` 所在目录 | `/project` | | `CMAKE_CURRENT_BINARY_DIR` | 当前构建目录 | `/project/build/src` | > 引用[^2]中说明:在子目录的 `CMakeLists.txt` 中,`CMAKE_CURRENT_SOURCE_DIR` 指向当前子目录,而 `CMAKE_SOURCE_DIR` 始终指向顶层目录。 #### 3. **核心作用** - **脚本调试**: 在复杂项目中追踪当前执行位置: ```cmake message("当前处理文件: ${CMAKE_CURRENT_LIST_FILE}") ``` - **相对路径计算**: 结合 `get_filename_component` 获取父目录: ```cmake get_filename_component(MODULE_DIR ${CMAKE_CURRENT_LIST_FILE} DIRECTORY) include(${MODULE_DIR}/helper.cmake) ``` - **模块化设计**: 在包含的脚本中定位资源: ```cmake # 在 /project/cmake/utils.cmake 中 set(UTILS_DIR "${CMAKE_CURRENT_LIST_DIR}/../resources") ``` #### 4. **动态更新特性** - 当通过 `include()` 或 `add_subdirectory()` 进入新文件时,变量值**自动更新**: ```cmake message("A: ${CMAKE_CURRENT_LIST_FILE}") # 输出主文件路径 include(sub/script.cmake) # 进入子脚本 message("B: ${CMAKE_CURRENT_LIST_FILE}") # 输出子脚本路径 ``` 退出子脚本后,变量值恢复为上级文件的路径。 #### 5. **实际应用场景** - **跨模块引用**: 在 ROS 项目中,根据当前包路径配置消息生成: ```cmake # 在 package_a/CMakeLists.txt 中 set(MSG_FILE "${CMAKE_CURRENT_LIST_DIR}/msg/AMessage.msg") generate_messages(${MSG_FILE}) ``` - **复用工具脚本**: 在共享的 `.cmake` 脚本中定位资源: ```cmake set(TOOL_DIR "${CMAKE_CURRENT_LIST_DIR}/tools") configure_file("${TOOL_DIR}/config.in" config.h) ``` > 引用[^1]中 `CMAKE_CURRENT_BINARY_DIR` 的用法类似,但 `CMAKE_CURRENT_LIST_FILE` 关注**源文件路径**而非构建路径。 ### 总结 `CMAKE_CURRENT_LIST_FILE` 是 CMake 脚本执行时的上下文感知变量,其值始终指向**当前正在解析的文件**。它解决了模块化 CMake 项目中路径定位的关键问题,尤其在跨目录包含脚本或资源时不可或缺。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值