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を1つずつループして、表示したい方法でそれらを取得したくありません-

順序を保持し、一意であるかどうかに関係なく、要求に基づいて行を引き出す単一のクエリを実際に作成する方法はありますか?

4

6 に答える 6

1

しようとしていることを行う代わりに、必要な一意の行を選択するだけです。フロントエンド コードでは、各一意の行を key=>value 構造に 1 回格納します。ここで、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 に答える
1

id=1 のレコードを含める必要があり、それらを取得する限り順序は問題にならない場合は、クエリを 2 つのクエリに分割できます。 =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

疑わしい質問に答えるもう 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 に答える