使 SQL 查询的第一个和最后一个结果唯一的最佳方法是啥?

Posted

技术标签:

【中文标题】使 SQL 查询的第一个和最后一个结果唯一的最佳方法是啥?【英文标题】:Best way to make first and last result unique from SQL query?使 SQL 查询的第一个和最后一个结果唯一的最佳方法是什么? 【发布时间】:2012-02-02 13:33:21 【问题描述】:

我有一个 SQL 查询,它输出 1000 个 sql 条目(有时少于 1000 个)。我希望第一个结果和最后一个结果是唯一的。

最好的方法是通过 IF 语句运行 1000 次,只是为了自定义第一行和最后一行?还是有更好的方法?

示例:

$sql=("SELECT * FROM `table` LIMIT 0, 1000");
$q = $conn->prepare($sql);
$q->execute($executearray);
$q->setFetchMode(PDO::FETCH_BOTH);

$i = 0;
$total = $q->rowCount();
while ($r = $q->fetch())

    $i++;

    // first result
    if ($i == 1) 
        echo "<div>" . $r['id'] . "</div>";
        echo "<div>" . $r['image'] . "</div>";
        echo "<div>" . $r['text'] . "</div>";

    // last result
     elseif ($i == $total) 
        echo "<div>" . $r['somethingelse'] . "</div>";

    // all other results
     else 
        echo "<div>" . $r['image'] . "</div>";
        echo "<div>" . $r['text'] . "</div>";
    

有没有办法做这样的事情...?

$sql=("SELECT * FROM `table` LIMIT 0, 1000");
$q = $conn->prepare($sql);
$q->execute($executearray);
$q->setFetchMode(PDO::FETCH_BOTH);

// first result
echo "<div>" . $r[0]['id'] . "</div>";
echo "<div>" . $r[0]['image'] . "</div>";
echo "<div>" . $r[0]['text'] . "</div>";

// results 2-999
while ($i <= $total - 1) 
    echo "<div>" . $r['somethingelse'] . "</div>";


// last result
echo "<div>" . $r[$total]['image'] . "</div>";
echo "<div>" . $r[$total]['text'] . "</div>";

【问题讨论】:

$i++ 在循环的开头? @webarto:这有什么问题? 您已将问题从简单的颜色更改更改为全新的输出。如果你想要的改变与你正在做的完全不同,那没关系。 @Madmartigan 如果你在循环中有中断/继续,你想知道实际执行了多少次迭代。 @webarto,如果您跳出循环并想知道您正在处理的项目怎么办? 【参考方案1】:

您可以使用更智能的 CSS 选择器,例如 :first-child 和 :last-child

css:

#queryresults p  color: blue 
#queryresults p:first-child  color: red 
#queryresults p:last-child  color: green  

html:

<div id="queryresults">
<p>result 1</p>
<p>result 2</p>
...
<p>result n-1</p>
<p>result n</p>
</div>

祝你好运!

【讨论】:

其实是redblue :) 谢谢 :) 当我意识到我自己编了颜色时,OP 改变了问题【参考方案2】:

编辑: 最简单的方法是在打印输出时更改forwhile 循环。我会在 for 循环中执行此操作,因为 while 循环保证您将至少获得一个结果并且将始终运行,但如果没有结果,for 循环将不会运行。

for($i=0; $i<results.length; $i++)
    if($i==0)
       # do unique first thing here
    elseif($i == results.length)
       # do unique last thing here
     else 
       # normal
    

或类似的东西。

你是什么意思结果是独一无二的?当您在生成的 HTML 页面中打印它们时,您想为它们设置不同的样式吗?

您可以为此使用 CSS 选择器。 :first-child:last-child

详情请见this entry on quirksmode

【讨论】:

我认为我的例子过于简单化了。我更新了它。它不适用于 CSS。 我已更新我的答案以提供更多详细信息。您需要在打印结果的循环中进行一些测试。 有没有办法像我刚刚添加的第二个示例一样? @supercoolville 你已经在这个例子中做了。不过,我看不出这两个问题之间的区别——我猜只是它们的打印顺序。您总是可以在我的答案中重新排序 if/else if/else 语句以实现相同的目标。【参考方案3】:

这通过仅循环记录 2count-1 来避免中间记录的 IF。

也就是说,它只会为您节省极少的 CPU 时间。你最好把精力集中在昂贵的代码上,而不是像这样微不足道的事情。

$sql=("SELECT * FROM `table` LIMIT 0, 1000");
$q = $conn->prepare($sql);
$q->execute($executearray);
$q->setFetchMode(PDO::FETCH_BOTH);

$i = 0;
$total = $q->rowCount();

// first result
if ($total > 0) 
    $r = $q->fetch();
    echo "<div>" . $r['id'] . "</div>";
    echo "<div>" . $r['image'] . "</div>";
    echo "<div>" . $r['text'] . "</div>";


// middle results
for($i=2; $i<$total; $i++)
    $r = $q->fetch();
    echo "<div>" . $r['image'] . "</div>";
    echo "<div>" . $r['text'] . "</div>";


// last result
if ($total > 1) 
    $r = $q->fetch();
    echo "<div>" . $r['somethingelse'] . "</div>";

另外,请注意 for 循环中有一个隐含的 IF:$1&lt;$total。当您的循环利用$q-&gt;fetch() 的结果来控制while 循环时。我更怀疑这将为您节省多少 CPU 时间。如果不测量实际的 CPU 周期,它甚至可能无法测量。

【讨论】:

好吧,速度差不多……哈哈。根据我运行的五个 10,000 行测试,它平均快 0.1 秒。我想我会保留 IF 的。【参考方案4】:

这可能是可行的方法,任何其他组件都会做几乎相同的事情。只是为您节省一些写作的提示:

while ($r = $q->fetch()) 
  $i++;
  echo "<p style='color:" . ($i ==1 ? 'red': $i == $total? 'blue':'green') . ";'>" . $r['id'] . "</p>"; 
 

【讨论】:

选择器是更好的主意,但没想到 :) 这还是1000个IF语句吗? 是的,我认为在这里使用 1000 个 if 没有什么特别的问题,就是这样。或者你有 CSS 选项。那只是......化妆品修复:)【参考方案5】:

与其拉回 1000 行数据,不如进行 2 次 sql 调用?查询第一条记录:

SELECT id FROM (SELECT id FROM `table` LIMIT 0, 1000) tmp ORDER BY id LIMIT 1

第二个:

SELECT id FROM (SELECT id FROM `table` LIMIT 0, 1000) tmp ORDER BY id DESC LIMIT 1

【讨论】:

这就是我想知道的...... 3个sql调用会比1000个IF更有效吗? 伙计,不要!这将是 slooooooooooow :) @supercoolville - 不。IF 非常琐碎。连接到数据库、验证、发送 sql 字符串、解析、处理并将结果传回,所有这些都多次使用网络流量,这听起来比几个本地 CPU 周期来执行 IF 语句要多得多。 主要区别在于将 1,000 行返回给 Web 应用程序将消耗更多的带宽,并且如果您经常进行此调用,则会成为一个繁重的 sql 进程。如果您正在寻找前往数据库的单次旅行,您可以使用 SELECT (SELECT id FROM (SELECT id FROM table LIMIT 0, 1000) tmp ORDER BY id LIMIT 1) as first,(SELECT id FROM (SELECT id FROM table LIMIT 0, 1000) tmp ORDER BY id DESC LIMIT 1) as last 如果您的 id 始终保证按顺序排列,您还可以使用:SELECT MIN(id) as first,MAX(id) as last FROM (SELECT id FROM table LIMIT 0, 1000) tmp

以上是关于使 SQL 查询的第一个和最后一个结果唯一的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在字典上循环 SQL 查询

PostgreSQL存储过程-基于SQL的存储过程

PostgreSQL存储过程-基于SQL的存储过程

如何重新加载经常崩溃的第 3 方 DLL

如何根据公历计算Oracle SQL中一个期间的第一个日期和最后一个日期

查找匹配查询的第一个和最后一个文档?