【问题标题】:selecting unique values from a column从列中选择唯一值
【发布时间】:2012-01-24 04:58:28
【问题描述】:

我有一个 MySQL 表,其中包含以下类型的信息:

    Date            product 
2011-12-12           azd
2011-12-12           yxm
2011-12-10           sdx
2011-12-10           ssdd  

这是我用来从该表中获取数据的脚本示例:

<?php

$con = mysql_connect("localhost","username","password");
if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }
mysql_select_db("db", $con);
$sql=mysql_query("SELECT * FROM buy ORDER BY Date");
while($row = mysql_fetch_array($sql))
{

 echo "<li><a href='http://www.website/". $row['Date'].".html'>buy ". date("j, M Y", strtotime($row["Date"]))."</a></li>";

    }
    mysql_close($con);
?> 

此脚本显示表格中的每个日期,例如

12.dec 2011
12.dec.2011
10.dec.2011
10.dec.2011

我只想显示唯一的日期,例如

12.dec.2011
10.dec.2011

【问题讨论】:

  • 不太确定合适的礼仪,但我需要与此类似的东西。我有一个像上面那样显示为所有日期列表的值列表。我想在一个日期序列的结尾和另一个日期序列的开头之间添加一些额外的空间。对此有何想法?

标签: php mysql sql


【解决方案1】:

在 MySQL 中使用DISTINCT 运算符:

SELECT DISTINCT(Date) AS Date FROM buy ORDER BY Date DESC;

【讨论】:

  • DISTINCT 的不幸问题是它只返回一个字段......所以如果你想要整个记录,DISTINCT 是没有价值的(除非它是一个 id 字段,你可以这样做第二个查询,其中 id 在该列表中)。不过,好消息是,如果由于 JOIN 导致多个重复结果,您可以执行 GROUP BY 并过滤完整结果。
  • 查德维克·迈耶不正确!您可以选择多个字段,但必须将它们分组。你可以这样: SELECT DISTINCT(name) AS yourName, id AS yourId FROM table GROUP BY name ORDER BY name 。你会感到惊讶!
【解决方案2】:

使用

SELECT DISTINCT Date FROM buy ORDER BY Date

所以 MySQL 会删除重复项

顺便说一句:当您从 MySQL 获得较大的结果时,在 SELECT 中使用显式列名会使用较少的 PHP 资源

【讨论】:

  • 你能解释一下“使用明确的列名”吗?哪种方式资源占用少,哪一种方式高?举个例子好吗?
  • 常见的用例是将数据库中的数据“流式”传输到 PHP 中的多维数组中;所以你的 PHP 进程只会用你可能不需要的数据来浪费内存。仅对于某些数据集,这可以忽略不计,但在处理数千行时,这可能会产生影响。
  • @NabeelKhan 而不是使用 SELECT * ... 使用 SELECT 第 1 列、第 2 列...除非您确实需要所有列。
  • @LPChip 使用 tablename.columnname 比仅使用 columnname 更有优势?
  • @NabeelKhan 加入表格时只需要 tablename.columnname。
【解决方案3】:

使用此查询获取值

SELECT * FROM `buy` group by date order by date DESC

【讨论】:

  • 我发现这没有帮助。假设您有 5 个项目,所有项目都具有相同的 date 但不同的 description。使用上述命令显示不同的dates,但只显示找到的第一个项目的description
  • @onebree - 在这种情况下,您可以使用GROUP BY date,description
【解决方案4】:

其余的几乎都是正确的,除了它们应该按日期 DESC 排序

SELECT DISTINCT(Date) AS Date FROM buy ORDER BY Date DESC;

【讨论】:

    【解决方案5】:

    DISTINCT 始终是获​​得唯一值的正确选择。你也可以在不使用它的情况下做它。那是GROUP BY。只需在查询末尾添加,后跟列名。

    SELECT * FROM buy GROUP BY date,description
    

    【讨论】:

      【解决方案6】:

      另一个DISTINCT 答案,但有多个值:

      SELECT DISTINCT `field1`, `field2`, `field3` FROM `some_table`  WHERE `some_field` > 5000 ORDER BY `some_field`
      

      【讨论】:

      • 或许可以解释一下这种技术(它没有试图与 OP 的问题相关联)的行为方式,以便研究人员可以决定它是否会按照他们的需要工作。
      • @mickmackusa - 正如描述中所述,这个答案没有什么特别之处,它只是演示了如何在 SELECT 查询中使用多个 DISTINCT 字段。
      • 那么它是否确保紧随关键字的列是唯一的,而其余列可能是唯一的,也可能不是唯一的?还是确保所有列的组合在结果集中都是唯一的?这就是不懂语法的研究人员可能会问自己的问题。这就是为什么你应该更慷慨地解释你的答案。您可以选择与我争论您的帖子“足够好”,但这将是徒劳的浪费时间。我的诚实意见是,这个答案可能更好地转移到一个要求包含多个列的结果集的问题。
      • 对不起,我没有时间回复。如果可以的话,投反对票,这通常是不同意答案的方式。祝你好运。
      • 我只会 DV 错误的答案和误导的答案,因为它们“有害”。这个答案根本没有通知。
      【解决方案7】:

      如果您还想以 JSON 格式输出每个日期的产品详细信息并且 MySQL 版本不支持 JSON 函数,请使用类似的内容。

      SELECT `date`,
      CONCAT('{',GROUP_CONCAT('{\"id\": \"',`product_id`,'\",\"name\": \"',`product_name`,'\"}'),'}') as `productsJSON`
      FROM `buy` group by `date` 
      order by `date` DESC
      
       product_id product_name     date  
      |    1     |     azd    | 2011-12-12 |
      |    2     |     xyz    | 2011-12-12 |
      |    3     |     ase    | 2011-12-11 |
      |    4     |     azwed  | 2011-12-11 |
      |    5     |     wed    | 2011-12-10 |
      |    6     |     cvg    | 2011-12-10 |
      |    7     |     cvig   | 2011-12-09 |
      
      RESULT
             date                                productsJSON
      2011-12-12T00:00:00Z    {{"id": "1","name": "azd"},{"id": "2","name": "xyz"}}
      2011-12-11T00:00:00Z    {{"id": "3","name": "ase"},{"id": "4","name": "azwed"}}
      2011-12-10T00:00:00Z    {{"id": "5","name": "wed"},{"id": "6","name": "cvg"}}
      2011-12-09T00:00:00Z    {{"id": "7","name": "cvig"}}
      

      SQL Fiddle试试吧

      如果您使用支持JSON 函数的MySQL 版本,则可以重写上述查询:

      SELECT `date`,JSON_OBJECTAGG(CONCAT('product-',`product_id`),JSON_OBJECT('id', `product_id`, 'name', `product_name`)) as `productsJSON`
      FROM `buy` group by `date`
      order by `date` DESC;
      

      两个都试试DB Fiddle

      【讨论】:

      • 哎呀!请不要鼓励通过 sql 中的聚合和字符串函数手动构造 json 字符串——这是一个不合适的工具,容易根据数据损坏。即使它在这种情况下有效,也会有一种更清洁、更易于维护的方式在 sql 之外执行此操作。
      • @mickmackusa 如果您使用的版本不支持本机 JSON 功能,您可以这样做。此外,破坏数据的问题是可以解决的。在上述情况下,需要注意的字段是product_name。谢谢你的评论。很久没听到Yikes了。
      【解决方案8】:

      取决于你需要什么。

      在这种情况下,我建议:

      SELECT DISTINCT(Date) AS Date FROM buy ORDER BY Date DESC;
      

      因为字段少,DISTINCT的执行时间比GROUP BY的执行时间要短。

      在其他情况下,例如有很多字段,我更喜欢:

      SELECT * FROM buy GROUP BY date ORDER BY date DESC;
      

      【讨论】:

        【解决方案9】:

        有一个特定的关键字来实现相同的。

        SELECT DISTINCT( Date ) AS Date 
        FROM   buy 
        ORDER  BY Date DESC; 
        

        【讨论】:

          猜你喜欢
          • 2012-03-28
          • 1970-01-01
          • 2018-06-25
          • 2013-06-09
          • 1970-01-01
          • 1970-01-01
          • 2014-07-14
          相关资源
          最近更新 更多