1

只是一个简单的问题:

我必须有一个具有多行的单个查询-某些行是相同的-并且必须在结果中保留行的顺序-

对我指的是什么的一些想法:

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 以使它们以我想要的方式显示-

有没有一种方法可以实际使用一个查询来保留订单并根据请求提取行,无论其是否唯一 -

4

6 回答 6

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
于 2012-02-23T12:36:51.207 回答
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;

但坦率地说,我怀疑你的数据模型到目前为止已经搞砸了,它是不可用的。

于 2012-02-23T12:38:41.760 回答
1

尝试

SELECT
    id,
    date
FROM items
WHERE id IN (1,2,1,3)
ORDER BY FIND_IN_SET(id, '1,2,1,3')
于 2012-02-23T12:38:47.253 回答
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
于 2012-02-23T12:55:09.497 回答
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;

保持给定的顺序。

于 2012-02-23T12:56:54.840 回答
1

而不是做你想做的事,只需选择你需要的唯一行。在前端代码中,在 key=>value 结构中存储每个唯一行一次,其中 key 是项目 ID,value 是您需要的有关该项目的任何数据。

一旦你有了它,你就可以使用前端逻辑以所需的顺序输出它们,包括重复。这将减少您尝试选择的冗余数据量。

例如,这不是可用的代码 - 所需的确切语法取决于您的脚本语言

-- 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
于 2012-02-23T12:35:25.977 回答