【问题标题】:Select multiple rows at different intervals以不同的间隔选择多行
【发布时间】:2012-01-11 19:42:48
【问题描述】:

是否可以在 MySQL 中选择一行然后错过 4 行然后错过 3 行然后错过 5 行然后循环直到表的末尾?

我在网上找到了一些 LIMIT 和 OFFSET 教程,它们有效,但只适用于一个offset。我需要多个。

我目前有这个设置可以在 PHP 中工作,但我觉得我的 PHP 代码很臃肿,因为我只知道实现这个的基本方法。

我的PHP代码如下

    $int_count = 0;
$result = mysql_query("SELECT * FROM guitar_tunings_chords WHERE note_id >= '27'");
while ( $row = mysql_fetch_array($result) ) {

    if ($int_count == 0)$n_1 = ($row["note"]);
    if ($int_count == 4)$n_2 = ($row["note"]);
    if ($int_count == 7)$n_3 = ($row["note"]);
    if ($int_count == 12)$n_4 = ($row["note"]);
    if ($int_count == 16)$n_5 = ($row["note"]);
    if ($int_count == 19)$n_6 = ($row["note"]);
    if ($int_count == 24)$n_7 = ($row["note"]);
    if ($int_count == 28)$n_8 = ($row["note"]);
    if ($int_count == 31)$n_9 = ($row["note"]);
    if ($int_count == 36)$n_10 = ($row["note"]);
    if ($int_count == 40)$n_11 = ($row["note"]);
    if ($int_count == 43)$n_12 = ($row["note"]);
    if ($int_count == 48)$n_13 = ($row["note"]);
    if ($int_count == 52)$n_14 = ($row["note"]);

    $int_count++;   

    }

我要做的是从大调音阶中只选择大三和弦音符。

我需要能够从表格中选择一个基本音符,然后以 3 个不同的间隔选择来创建和弦。


更新

            $result2 = mysql_query("SELECT * 
            FROM `guitar_tunings_links`
            JOIN guitar_tunings_chords ON guitar_tunings_links.".$funtion_string." = guitar_tunings_chords.note
            WHERE tuning =  '".$chrd_tn."'") or die(mysql_error());

                while ( $row = mysql_fetch_array($result2) ) {
                    $bridge_note = ($row["note_id"]);           
                }/*
                var_dump ($key_note);
                var_dump ($bridge_note);
                var_dump ($funtion_string);
                var_dump ($chrd_tn);*/
                    // SELECT * FROM `guitar_tunings_chords` WHERE `note_id` >= 28 LIMIT 0,8
                $result4 = mysql_query("SELECT * FROM `guitar_tunings_chords` WHERE `note_id` >= ".$bridge_note." LIMIT ".$tuning_capo.",8") or die(mysql_error());
                while ( $row = mysql_fetch_array($result4) ) {

                    //Notes
                    $note = ($row["note"]); 

                    // Replace # with z
                    $note = str_replace("#", "z", $note);

                    // Distinguish nut notes on or off
                    if (preg_match("/\b".$note."\b/i", $notes_array)) {
                        $n_nut_style = 'note_nut_on';
                    } else { $n_nut_style = 'note_nut_off'; 
                    }

                    // Distinguish fretboard notes on or off
                    if (preg_match("/\b".$note."\b/i", $notes_array)) {
                        $n_style = 'note_on';
                    } else { $n_style = 'note_off'; 
                    }

【问题讨论】:

  • 我知道 PHP,但我对吉他和弦一无所知。我认为你应该详细说明这部分。
  • 您可以更改偏移量并再次发送查询
  • 1.您可能应该更喜欢 array 或其他一些复合数据类型,而不是大量以索引为后缀的变量。例如,array_push($notes, $row["note"])。 2. 您应该明确地订购该查询,而不是依赖引擎意外选择您想要的顺序,即使这恰好是“隐式确定性事故”。
  • 我的数据库中有 88 个音符,与全尺寸钢琴差不多。如果我以 4、3、5 的间隔演奏每个音符,我将弹奏 C 和弦。我想选择所有这些音符,但将那些落在间隔上的音符标记为“开”,其余的标记为“关”。然后我可以为吉他生成和弦图。喜欢这个页面gtdb.org/tuning_links/chord_generator/chords.php

标签: php mysql offset


【解决方案1】:

您必须将其应用于您的确切表格,但它应该工作得很好。

select * 
  from (select @i := @i+1 as count, 
               gtc.* from guitar_tunings_chords gtc
         where note_id >= 27) counts 
  join (select @i := -1 as counter) dummy
 where count % 12 = 0 
    or (count-4) % 12 = 0 
    or (count-7) % 12 = 0;

%12给出一个完整的skip循环,-4和-7(和-0)是每个循环内的内部偏移量。

【讨论】:

  • +1 用于模拟 ROW_NUMBER() 并将您的方式修改为所需的行,如 @Wrikken also suggested
  • ROW_NUMBER 确实应该是 MySQL 中的原生函数。
  • +1。值得一提的是,@i 初始化可以放在派生表中:... JOIN (SELECT @i := -1 AS "counter") dummy...。我提出它是因为下一个问题几乎总是,“很好,但是我如何在一个查询中做到这一点?” :)
  • 我补充说。它增加了一些肤色,但我认为这是值得的。我通常只写存储过程,所以我通常不会想到“需要成为在线用户,因为我使用 PHP/hibernate/whatever”。
  • 这看起来确实很有趣,虽然我无法理解我应该用它做什么?我不确定您将其应用于我的确切表格是什么意思?这在PHP中吗?我尝试将其作为查询应用到 PHPMyAdmin;它说我的查询成功,但没有结果!?我可以将每个结果修剪成自己的变量吗?
【解决方案2】:

试试这个...我自己没有尝试过,但在我的脑海中它应该可以工作:)

$row_count = 0;
$result = mysql_query("SELECT * FROM guitar_tunings_chords WHERE note_id >= '27'");
$notes = array(); // Notes array
$pattern = array(4,3,5); // Pattern to skip notes
$i = 0; // For pattern position
$first = true;
while ($row = mysql_fetch_array($result)) {
    if($first) { // Add the first note
        $notes[] = $row["note"];
        $first = false;
    } else {
        if($row_count == $pattern[$i]) {
            // Add note
            $notes[] = $row["note"];
            $i++; // Change pattern position
            // Jump to start of pattern
            if($i == 3)
                $i = 0;
            // Reset count
            $row_count = -1;
        }
    }
    $row_count++;
}

【讨论】:

  • 我确实试过这个。但理想情况下,我需要将每个选定的注释添加到一个变量中,然后我可以应用一个样式来指示它是打开还是关闭。所有的笔记都需要打印出来,我只需要指出哪些是打开的。我正在处理的文件在这里..
  • 感谢您的回复!它看起来不错,因为我可以通过转换 Excel 单元格之间的逗号来完成所有的间隔添加。
  • 不知道你的意思,所有的笔记都存储在$notes数组中
  • 我看不出我的 PHP 知识薄弱,我怎么能取出 naotes 并将它们中的每一个应用到它自己的变量中,比如这个 global $chrd_tn, $n_1, $n_2, $n_3, $n_4, $n_5, $n_6, $n_7, $n_8, $n_9, $n_10, $n_11, $n_12, $n_13, $n_14, $tuning_capo;
  • 不知道$chrd_tn或$tuning变调夹是什么意思,你可以通过$notes[0]等来引用每个音符。
【解决方案3】:

我会考虑可能使用带有间隔(0、4、7、12、16、19 等)的 chord_note 表,并将其用作 SELECT 的一部分,添加初始 note_id 值 (27) + 条目在 chord_note 表中

SELECT * 
  FROM guitar_tunings_chords 
 WHERE note_id IN ( SELECT 27+chord_interval 
                      FROM chord_note
                  )

更奇葩的是,你甚至可以扩展 chord_note 表来保存不同音阶的不同间隔细节,只需修改子选择

【讨论】:

  • 它假定 ID 是有意义的,但如果是,它会起作用(不过我会抛出一个 ORDER BY..)
  • 虽然,如果没有子选择,它可能是:WHERE id - 27 >= 0 AND ( (( id - 27) % 12 ) = 4 OR ( (id-27) % 12 ) = 7 OR ( id - 27) % 12 = 0) LIMIT 14
  • 感谢您的时间标记。这当然是我现在正在考虑的事情。虽然我实际上并不了解您的 SQL 查询,但我认为一个只有间隔的新表将是实现这一目标的好方法。我上面的代码仅适用于一个和弦。我目前正在处理这个文件gtdb.org/tuning_links/chord_generator/chords.php
  • 我最终使用了你的 SQL 语句 Wrikken。谢谢你。我花了一段时间来解决它并使其适合我的功能,但它的运行就像我在页面上想要的那样。当我尝试将页面包含在网站中时,我遇到了 SQL 错误。我的变量之一似乎是空的。但我不知道如何阻止它。任何的想法?它在此页面 gtdb.org/tuning_links/chord_generator/chords.php?capo=2 上运行良好,但在此页面上它丢失了变量 gtdb.org/tests
  • 我在顶部添加了部分功能,该功能会导致我的问题出现错误。问题所在的代码是这个“.$bridge_note”。限制 ".$tuning_capo.",8"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-13
  • 2015-08-01
相关资源
最近更新 更多