只是一个简单的问题:
我必须有一个包含多行的单个查询 - 某些行是identicle - 并且行的顺序必须保留在结果中 -
关于我所指的内容的一些想法:
SELECT id,date
FROM items
WHERE id IN (1,2,1,3)
ORDER BY id=1 DESC,id=2 DESC,id=1 DESC,id=3 DESC;
不幸的是,mysql的结果是:
1,2,3
不是1,2,1,3
它会删除我在结果中必须包含的副本,以便在同一网页上的多个面板中显示 -
我真的不想一个接一个地循环每个id来让它们按我想要的方式显示 -
有没有办法实际拥有一个单独的查询来保存订单并根据请求提取行是否唯一 -
答案 0 :(得分:1)
只需选择您需要的唯一行,而不是按照您的要求进行操作。在前端代码中,将每个唯一行存储在一个key =>值结构中,其中key是项ID,值是您需要的有关该项的任何数据。
一旦你有了,你可以使用前端逻辑以所需的顺序输出它们,包括重复。这将减少您尝试选择的冗余数据量。
例如这不是可用的代码 - 所需的确切语法取决于您的脚本语言
-- setup a display order
displayOrder= [1,2,1,3];
-- select data from database, order doesn't matter here
SELECT id,date
FROM items
WHERE id IN (displayOrder);
-- cache the results in a key=> value array
arrCachedRows = {};
for (.... each db row returned ...) {
arrCachedRows[id] = date;
}
-- Now output in desired order
for (listIndex in displayOrder) {
-- Make sure the index is cached
if (listIndex exists in arrCachedRow) {
echo arrCachedRows[listIndex ];
}
}
如果你发出警告,你必须坚持使用UNION
如果您违反上述建议并且绝对必须按照该顺序将它们放回1个查询中,那么添加另一行将强制执行行顺序。请参阅下面的查询,其中我使用变量@subIndex将递增值添加为subIndex。这反过来允许您按此重新排序,它将按要求的顺序。
SELECT
i.*
FROM (
SELECT @subIndex:=@subIndex+1 AS subIndex, id, date FROM items where id = 1
UNION
SELECT @subIndex:=@subIndex+1 AS subIndex, id, date FROM items where id = 2
UNION
SELECT @subIndex:=@subIndex+1 AS subIndex, id, date FROM items where id = 1
UNION
SELECT @subIndex:=@subIndex+1 AS subIndex, id, date FROM items where id = 3
) AS i,(SELECT @subIndex:=0) v
ORDER BY i.subIndex
或稍微更清洁的版本,将项目选择保持到外部并隐藏子索引
SELECT
items.*
FROM items
-- initialise variable
INNER JOIN (SELECT @subIndex:=0) v
-- create a meta-table with the ids desired in the order desired
INNER JOIN (
SELECT @subIndex:=@subIndex+1 AS subIndex, 1 AS id
UNION
SELECT @subIndex:=@subIndex+1 AS subIndex, 2 AS id
UNION
SELECT @subIndex:=@subIndex+1 AS subIndex, 1 AS id
UNION
SELECT @subIndex:=@subIndex+1 AS subIndex, 3 AS id
) AS i
ON i.id = items.id
-- order by the subindex from i
ORDER BY i.`subIndex` ASC
答案 1 :(得分:1)
如果你想要包含id = 1的记录,并且只要你得到它们,顺序就无关紧要了,你可以将查询分成两个查询,一个用于(1,2,3)联合所有其他查询查询id = 1或只是执行:
... In (1,2)
Union all
... In (1,3)
示例:
Select * from
(Select case id when 1 then 1 when 2 then 2 as pseudocol, othercolumns
From table where Id in (1,2)
Union all
Select case id when 1 then 3 when 3 then 4 as pseudocol, othercolumns
From table where Id in (1,3)) t order by pseudocol
答案 2 :(得分:1)
您的查询将永远不会起作用,因为忽略了IN
子句值列表中的重复值。 唯一方法是使用UNION ALL
:
SELECT id, date FROM items where id = 1
UNION ALL
SELECT id, date FROM items where id = 2
UNION ALL
SELECT id, date FROM items where id = 1
UNION ALL
SELECT id, date FROM items where id = 3;
但坦率地说,我怀疑你的数据模型到目前为止已经搞砸了它无法使用。
答案 3 :(得分:1)
试
SELECT
id,
date
FROM items
WHERE id IN (1,2,1,3)
ORDER BY FIND_IN_SET(id, '1,2,1,3')
答案 4 :(得分:1)
回答可疑问题的另一种严谨方法:
SELECT
items.id,
items.date
FROM
items
JOIN
( SELECT 1 AS id, 1 AS ordering
UNION ALL
SELECT 2, 2
UNION ALL
SELECT 1, 3
UNION ALL
SELECT 3, 4
) AS auxilary
ON
auxilary.id = items.id
ORDER BY
auxilary.ordering
答案 5 :(得分:1)
另一种方法(未经测试,但应该给你一个想法):
CREATE TEMPORARY TABLE tt (id INT, ai int unsigned auto_increment primary key);
INSERT INTO tt (id) VALUES (1), (2), (1), (3);
SELECT
id,
date
FROM items JOIN tt USING (id)
ORDER BY tt.ai;
保持给定的顺序。