如何在sql中选择特定范围内的行?

时间:2020-06-21 04:21:43

标签: php sql

我正在创建一个简单的消息传递Web应用程序。人们可以通过登录轻松地发送或接收短信。只需单击特定的联系人姓名,您便会获得带有所有先前消息的聊天框。现在的问题是,任何包含大量消息的对话都将花费很长时间来加载聊天框。所以我想第一次在聊天框中显示最新的(按发送时间顺序排序)10条消息。在聊天框的顶部,我想提供一个按钮,点击该用户将获得前10条消息(通过sendtime desc排序),并将一直持续到用户获得最后一条消息为止。 我正在使用PHP AJAX。 我用来获取前10条消息的代码在这里

    $sql2="select * from messages where sender='$user1' and reciever='$user2' or reciever='$user1' and 
sender='$user2' order by sendingTime desc";
$res2=mysqli_query($con,$sql2);
$num=mysqli_num_rows($res2);
if($num<=10){
for($i=1;$i<=$num;$i++){
$row2=mysqli_fetch_array($res2);
$data2[]=$row2;
}
}else{
for($i=1;$i<=10;$i++){
$row2=mysqli_fetch_array($res2);
$data2[]=$row2;
}
}

但是我不知道如何选择接下来的10条消息行。请帮忙。

我的“消息”数据库结构 1 idPrimary int(11)否无AUTO_INCREMENT更改更改丢弃丢弃
更多更多 2个发件人varchar(100)latin1_swedish_ci否无更改更改丢弃丢弃
更多更多 3个接收器varchar(100)latin1_swedish_ci否无更改更改丢弃丢弃
更多更多 4 msg varchar(5000)latin1_swedish_ci否无更改更改丢弃丢弃
更多更多 5 sendingTime varchar(100)latin1_swedish_ci否无更改更改丢弃丢弃
更多更多 6 deliveryTime varchar(100)latin1_swedish_ci否无更改更改丢弃丢弃
更多更多 7 status int(1)否

2 个答案:

答案 0 :(得分:1)

警告!:您当前对SQL注入(SQLI攻击)持开放态度。请同时使用Prepared StatementsParametized queries来使用mysqliPDO。您的数据库面临巨大风险!不要相信任何用户输入!

话虽如此,我将使用 mysqli预处理语句和参数化查询继续这个答案。

查询中通常需要使用LIMIT运算符。有关LIMIT运算符的更多信息,请参见here

示例:

SELECT
    *
FROM
    messages
WHERE
    sender = 1 AND receiver = 2
    OR ( receiver = 1 AND sender = 2)
LIMIT 10;

DB小提琴here

在AJAX函数中,您需要解析一个值,该值将用作LIMIT子句中的变量。每次点击“加载更多” ,就会将该值增加10。

这是您的PHP页面的外观:

<?php
// Your user variables
$user1 = $_POST['user1'];
$user2 = $_POST['user2'];

// Your amount of messages to be loaded
$loadMessages = $_POST['messageAmount'];

if(empty($loadMessages )) {
   $loadMessages = 0; 
}

// DB variables
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "myDB";

// Error handling
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);

/*
Declare the query.
One thing to note from a select statement,
is that it is generally considered better practice
to list the fields you want to fetch.
Even if it's considered to be all fields.
So I would recommend doing that over "SELECT *".
*/
$sql = "SELECT
            *
        FROM
            messages
        WHERE
            sender = ?
            AND receiver = ? 
            or (reciever = ? and sender = ?)
        LIMIT (10 + ?)
        ORDER BY
            sendingTime DESC";

/*
Prepare and bind 
The variable identifiers are based on assuming the sender and receiver
are int fields. Change the identifier if that's not the case.

Identifiers:
-s string
-i int
-d double
-b BLOB
*/
$stmt = $conn->prepare($sql);
$stmt->bind_param('iiiii', $user1, $user2, $user1, $user2, $loadMessages);

// Execute the query
$stmt->execute();

// Get result of query
$result = $stmt->get_result();

// Close connection
$stmt->close();
$conn->close();
?>

要遍历结果:

<?php
// Check if any returned rows?
if($result->num_rows > 0) {
    // Loop through the result(s)
    while ($data = $result->fetch_assoc()) {
        echo $data['field_name'];
    }
} else {
    // Something here?
}
?>

答案 1 :(得分:0)

尝试 BETWEEN 运算符

在value1和value2之间的column_name位置;

设置value1和value2的条件

Check syntax

相关问题