我有这个问题:
select
name
from
provinces
WHERE
province_id IN(1,3,2,1)
ORDER BY FIELD(province_id, 1,3,2,1)
IN()中的值数是动态的
如何使用给定的ORDER BY获得所有行甚至重复(在此示例中为> 1)?
结果应该是这样的:
name1
name3
name2
name1
加上我不应该使用UNION ALL:
select * from provinces WHERE province_id=1
UNION ALL
select * from provinces WHERE province_id=3
UNION ALL
select * from provinces WHERE province_id=2
UNION ALL
select * from provinces WHERE province_id=1
答案 0 :(得分:4)
这里需要一个帮助表。在SQL Server上可以是:
SELECT name
FROM (Values (1),(3),(2),(1)) As list (id) --< List of values to join to as a table
INNER JOIN provinces ON province_id = list.id
更新:在MySQL Split Comma Separated String Into Temp Table中可用于将字符串参数拆分为帮助程序表。
答案 1 :(得分:1)
要多次获取同一行,您需要加入另一个表。我建议只创建一次(!)辅助表。该表只包含一系列自然数(1,2,3,4 ......等)。这样的表可用于许多其他目的。
以下是创建它的脚本:
create table seq (num int);
insert into seq values (1),(2),(3),(4),(5),(6),(7),(8);
insert into seq select num+8 from seq;
insert into seq select num+16 from seq;
insert into seq select num+32 from seq;
insert into seq select num+64 from seq;
/* continue doubling the number of records until you feel you have enough */
对于手头的任务,没有必要添加许多记录,因为您只需要确保in
条件中的重复次数不会超过上述seq
表中的重复次数。我猜128会很好,但可以随意将记录数量增加一倍。
完成上述操作后,您可以编写如下查询:
select province_id,
name,
@pos := instr(@in2 := insert(@in2, @pos+1, 1, '#'),
concat(',',province_id,',')) ord
from (select @in := '0,1,2,3,1,0', @in2 := @in, @pos := 10000) init
inner join provinces
on find_in_set(province_id, @in)
inner join seq
on num <= length(replace(@in, concat(',',province_id,','),
concat(',+',province_id,',')))-length(@in)
order by ord asc
示例数据和样本in
列表的输出:
| province_id | name | ord |
|-------------|--------|-----|
| 1 | name 1 | 2 |
| 2 | name 2 | 4 |
| 3 | name 3 | 6 |
| 1 | name 1 | 8 |
您需要将赋值中的值列表放入变量@in
。为了使它工作,每个有效的id必须包含在逗号之间,这就是为什么在开始和结束时都有一个虚拟零。
通过加入seq
表,结果集可以增长。从seq
为特定省份记录加入的记录数等于列表province_id
中相应@in
的出现次数。
没有开箱即用的功能来计算此类事件的数量,因此num <=
右侧的表达式可能看起来有点复杂。但它只是为@in
中的每个匹配添加一个字符,并检查该操作的长度增长。这种增长是发生的次数。
在select
子句中,返回province_id
列表中@in
的位置并用于对结果集进行排序,因此它对应于@in
中的顺序}列表。事实上,该位置是参考@in2
,@in
的副本,但允许更改:
在计算此@pos
时,@pos
中找到的@in2
上的数字被#
字符销毁,因此province_id
相同在同一个位置再也找不到了。
答案 2 :(得分:0)
目前还不清楚你究竟想要什么,但这就是为什么它不能按你想要的方式工作。 IN关键字是创建像......这样的语句的简写。其中province_id = 1 OR province_id = 2 OR province_id = 3 OR province_id = 1.由于province_id = 1在该语句的开头被评估为true,因此它不是如果它再次被包括在内,那已经是真的了。这与结果是否返回重复无关。