0

あなたが持っていると仮定します

id   /   value
1        2
1        3
1        6
2        3
3        1 
3        3
3        6

そして、id グループごとに少なくとも n 行を取得したいと思います。たとえば、n = 4 とします。さらに、カウンターを列として追加すると役立ちます。したがって、結果は次のようになります。

counter /  id   /  value
1          1       2
2          1       3
3          1       6
4          null    null
1          2       3
2          null    null
3          null    null
4          null    null
1          3       1
2          3       3
3          3       6
4          null    null

よろしく

4

2 に答える 2

0

次のブログ投稿では、クエリの解決策について説明しています 。SQL:グループごとに上位Nレコードを選択します。

これには、追加の小さな数値テーブルが必要です。これは、文字列ウォーキング手法を介してグループごとの上位N個の値を「反復」するために使用されます。MySQLがウィンドウ関数をサポートしていないという事実を克服する方法としてGROUP_CONCATを使用します。これはまた、それがきれいな光景ではないことを意味します!

この手法の利点は、サブクエリを必要とせず、テーブルのインデックスを最適に利用できることです。

質問への回答を完了するには、列を追加する必要があります。グループごとのアイテムごとにカウンターをリクエストしました。

これは、世界のサンプルデータベースを使用して、大陸ごとに上位5つの郡を選択した例です。

CREATE TABLE `tinyint_asc` (
 `value` tinyint(3) unsigned NOT NULL default '0',
 PRIMARY KEY (value)
) ;

INSERT INTO `tinyint_asc` VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23),(24),(25),(26),(27),(28),(29),(30),(31),(32),(33),(34),(35),(36),(37),(38),(39),(40),(41),(42),(43),(44),(45),(46),(47),(48),(49),(50),(51),(52),(53),(54),(55),(56),(57),(58),(59),(60),(61),(62),(63),(64),(65),(66),(67),(68),(69),(70),(71),(72),(73),(74),(75),(76),(77),(78),(79),(80),(81),(82),(83),(84),(85),(86),(87),(88),(89),(90),(91),(92),(93),(94),(95),(96),(97),(98),(99),(100),(101),(102),(103),(104),(105),(106),(107),(108),(109),(110),(111),(112),(113),(114),(115),(116),(117),(118),(119),(120),(121),(122),(123),(124),(125),(126),(127),(128),(129),(130),(131),(132),(133),(134),(135),(136),(137),(138),(139),(140),(141),(142),(143),(144),(145),(146),(147),(148),(149),(150),(151),(152),(153),(154),(155),(156),(157),(158),(159),(160),(161),(162),(163),(164),(165),(166),(167),(168),(169),(170),(171),(172),(173),(174),(175),(176),(177),(178),(179),(180),(181),(182),(183),(184),(185),(186),(187),(188),(189),(190),(191),(192),(193),(194),(195),(196),(197),(198),(199),(200),(201),(202),(203),(204),(205),(206),(207),(208),(209),(210),(211),(212),(213),(214),(215),(216),(217),(218),(219),(220),(221),(222),(223),(224),(225),(226),(227),(228),(229),(230),(231),(232),(233),(234),(235),(236),(237),(238),(239),(240),(241),(242),(243),(244),(245),(246),(247),(248),(249),(250),(251),(252),(253),(254),(255);

SELECT
  Continent,
  SUBSTRING_INDEX(
    SUBSTRING_INDEX(
      GROUP_CONCAT(Name ORDER BY SurfaceArea DESC),
      ',', value),
    ',', -1)
    AS Name,
  CAST(
    SUBSTRING_INDEX(
      SUBSTRING_INDEX(
        GROUP_CONCAT(SurfaceArea ORDER BY SurfaceArea DESC),
        ',', value),
      ',', -1)
    AS DECIMAL(20,2)
    ) AS SurfaceArea,
  CAST(
    SUBSTRING_INDEX(
      SUBSTRING_INDEX(
        GROUP_CONCAT(Population ORDER BY SurfaceArea DESC),
        ',', value),
      ',', -1)
    AS UNSIGNED
    ) AS Population,
    tinyint_asc.value AS counter
FROM
  Country, tinyint_asc
WHERE
  tinyint_asc.value >= 1 AND tinyint_asc.value <= 5
GROUP BY
  Continent, value
;
于 2012-07-06T17:21:57.680 に答える
0

との組み合わせはユニークだidと思います。valueMySQL変数を使用せずにそれを行う方法は次のとおりです。

SELECT
    a.n AS counter, 
    b.id, 
    b.value
FROM
    (
        SELECT 
            aa.n, 
            bb.id
        FROM
            (
                SELECT 1 AS n UNION ALL
                SELECT 2 AS n UNION ALL
                SELECT 3 AS n UNION ALL
                SELECT 4 AS n
            ) aa
        CROSS JOIN 
            (
                SELECT DISTINCT id
                FROM tbl
            ) bb
    ) a
LEFT JOIN
    (
        SELECT aa.id, aa.value, COUNT(*) AS rank
        FROM tbl aa
        LEFT JOIN tbl bb ON aa.id = bb.id AND aa.value >= bb.value
        GROUP BY aa.id, aa.value
    ) b ON a.id = b.id AND a.n = b.rank
ORDER BY
    a.id, 
    a.n
于 2012-07-04T03:19:47.987 に答える