【问题标题】:How to select one row only? [closed]如何只选择一行? [关闭]
【发布时间】:2012-05-17 08:14:53
【问题描述】:

我有两张桌子

   NAME
   +----+---------+
   | id |   name  |
   +----+---------+
   |  1 |   ABC   |
   |  2 |   CCC   |
   +----+---------+

   TBL_STATUS
   +----+-----------+--------+
   | id |  name_id  | status |
   +----+-----------+--------+
   |  1 |     1     |   KU   |
   |  2 |     1     |   HP   |
   |  3 |     1     |   HK   |
   |  4 |     2     |   KU   |
   |  5 |     2     |   HP   |
   +----+-----------+--------+

我选择并连接在一起 (INNER JOIN) 这 2 个表。 这是我的查询结果。

   +---------+--------+
   |   name  | status |
   +---------+--------+
   |   ABC   |   HK   |
   |   ABC   |   HP   |
   |   ABC   |   KU   |
   |   CCC   |   HP   |
   |   CCC   |   KU   |
   +---------+--------+

每个名字可以有 3 个状态。 HK、HP 或 KU。 对于最新状态,我只希望每个名称都有一行。 例如:

   +---------+--------+
   |   name  | status |
   +---------+--------+
   |   ABC   |   HK   |
   |   CCC   |   HP   |
   +---------+--------+

状态优先级应首先显示 HK(如果有), 那么如果没有HK显示HP,以此类推..

【问题讨论】:

  • 我有这个,我有那个。现在给我写code
  • 你能定义最新状态吗?
  • First 在输入表中您没有日期,但在输出表中您有数据。 第二到目前为止,您还没有展示您尝试过的内容。如果没有您的努力,SO 上的任何人都不会准备好帮助您。

标签: php mysql sql sql-server


【解决方案1】:

你的最终输出是正确的

   +----+---------+--------+
   | id |   name  | status |
   +----+---------+--------+
   |  1 |   ABC   |   HK   | -- Need to remove
   |  2 |   ABC   |   HP   | -- Need to remove
   |  3 |   ABC   |   KU   |
   |  5 |   CCC   |   HP   | -- Need to remove
   |  6 |   CCC   |   KU   | 
   +----+---------+--------+

您只需将其限制为每个名称的最大 ID,这在下面使用聚合查询上的 INNER JOIN 来实现。

SELECT  Name, Status
FROM    Name
        INNER JOIN tbl_Status
            ON tbl_Status.Name_ID = Name.ID
        INNER JOIN
        (   SELECT  MAX(ID) AS MaxStatusID
            FROM    Tbl_Status
            GROUP BY Name_ID
        ) MaxStatus
            ON MaxStatusID = tbl_Status.ID

【讨论】:

  • 如果顺序不同,这将不起作用。 IE。原来是 KU 的东西变成了 HP。
  • @llion 考虑到当前数据,它甚至无法正确工作。似乎 OP 想要按字母顺序排列状态,所以我可以写 SELECT Name, MAX(Status) AS Status FROM Name INNER JOIN Status ON Name.ID = Status.Name_ID GROUP BY Name 来返回正确的结果,但只能在一种特定情况下工作。但是,OP 要求将结果集限制为每个名称一行的 logic(在早期版本中)。这似乎是演示 ROW_NUMBER() 函数不可用的标准技术的最简洁方式。
【解决方案2】:

您必须从TBL_STATUS 中找到 max(id),然后将所有数据连接在一起,例如:

SELECT n.name, st3.status 
FROM name AS n 
LEFT JOIN 
  (SELECT st1.name_id, MAX(st1.id) AS max_id
     FROM TBL_STATUS st1 
     GROUP BY name_id) AS st2
  ON n.id=st2.name_id
LEFT JOIN 
  TBL_STATUS st3
  ON st2.max_id = st3.id 

【讨论】:

  • 让我们忽略日期,因为我想知道逻辑。当然我试过了,这只是我在这个查询中的一部分问题。
  • 将您的 LEFT JOINs 更改为 INNER JOINs。否则,您最终将在输出中得到 5 行,但其中 3 行的状态将为 NULL
猜你喜欢
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-08
相关资源
最近更新 更多