【问题标题】:SQL selecting from multiple tables and ordering by certain conditionsSQL从多个表中选择并按特定条件排序
【发布时间】:2015-11-20 19:23:55
【问题描述】:

我有 2 张桌子,customertickets

我希望能够从门票表中选择并通过以下方式订购:

tickets.priority 然后customer.category_priority 然后tickets.queue_time

我有这个问题:

SELECT t.*
from tickets t
  JOIN customer c ON t.company = c.sequence
WHERE t.status <> 'Completed' AND t.queue = 'Y'
ORDER BY field(t.priority, 'Critical', 'High', 'Medium', 'Low'), t.queue_time ASC

这对tickets.prioritytickets.queue_time 非常有用

但我不确定如何合并customer.category_priority

所以在客户表中,我的列的名称如下:

priority_computers
priority_telephone
priority_software

所有 INT 字段,值为 0、1 或 2

tickets 中的行有一个category 列,可以是ComputersTelephoneSoftware,这就是需要链接到上面的内容。

因此,如果客户行的 priority_computers 为 2,而 tickets 行是 category = 'Computers',则该行将位于列表顶部,因为客户记录的优先级为 2,它还将包含其他ORDER BY条件

例子:

客户:

  • A 公司 priority_computers = 1
  • 公司 B priority_computers = 2
  • C 公司 priority_computers = 3

示例一:

  • Ticket 1 公司 A 优先级 = 中等类别 = 计算机 queue_time = 2015-11-20 08:00
  • Ticket 2 公司 B 优先级 = 中等类别 = 计算机 queue_time = 2015-11-20 10:00:00
  • Ticket 3 公司 C 优先级 = 中等类别 = 计算机 queue_time = 2015-11-20 08:30:00

这应该按以下顺序输出:

  • 票 3
  • 票2
  • 票 1

示例 2:

  • 工单 1 公司 B 优先级 = 高类别 = 计算机
    queue_time = 2015-11-20 12:00
  • Ticket 2 公司 A 优先级 = 中等类别 = 计算机 queue_time = 2015-11-20 07:00:00
  • Ticket 3 公司 C 优先级 = 中等类别 = 计算机 queue_time = 2015-11-20 07:00:00

这应该按以下顺序输出:

  • 票 1
  • 票 3
  • 票2

【问题讨论】:

  • 你能给出示例数据和预期输出吗?
  • 检查我的更新,我给出了一些虚拟数据的例子,希望对您有所帮助
  • 所以每张票只有一位顾客? (JOIN customer c ON t.company = c.sequence 有点令人困惑,我原以为是JOIN customer c ON t.customer_id = c.customer_id)。还是一张票可以有更多的顾客?如果有,如何处理?
  • 每张票有一位顾客,但每位顾客可以拥有超过 1 张票
  • 如果有更好的方法将此信息存储在数据库中,那么我愿意接受意见

标签: php mysql sql


【解决方案1】:

如果我理解正确,那么您的问题是您必须以某种方式将数据与列名匹配。

  • customer.priority_computers for ticket.category = 'Computers'
  • customer.priority_telephone for ticket.category = 'Telephone'
  • customer.priority_software for ticket.category = '软件'

这表明存在数据库设计缺陷。应该有一个 customer_priority 表,每行包含一个客户、一个类别和相关值。然后你就可以简单地加入了。

按原样,您必须检查数据内容并决定要在查询中使用的列:

SELECT t.*
from tickets t
  JOIN customer c ON t.company = c.sequence
WHERE t.status <> 'Completed' AND t.queue = 'Y'
ORDER BY field(t.priority, 'Critical', 'High', 'Medium', 'Low')
  , case t.category 
      when 'Computers' then c.priority_computers
      when 'Telephone' then c.priority_telephone
      when 'Software' then c.priority_software
    end
  , t.queue_time ASC

更新:如果您有一个 customer_priority 表,这是您要编写的查询。您会看到,您的查询不再需要知道存在哪些类别以及如何处理它们。

SELECT t.*
from tickets t
  JOIN customer c ON t.company = c.sequence
  JOIN customer_priority cp ON cp.customer_id = c.sequence
                            AND cp.category = t.category
WHERE t.status <> 'Completed' AND t.queue = 'Y'
ORDER BY field(t.priority, 'Critical', 'High', 'Medium', 'Low')
  , cp.priority_value
  , t.queue_time ASC

此外:如前所述,有一张桌子customer 很奇怪,但在tickets 中,它不称为客户,而是公司,并且在customer 表本身也不称为 customer 编号或 ID,而是 sequence。这会降低查询的可读性。我建议,如果可能的话,您可以更改名称,以便它们保持一致。

此外,您的查询不必知道“关键”和“高”的含义。应该有一个优先级表,其中每个优先级都有一个名称和一个值,因此查询可以简单地选择该值并使用它,而无需了解有关优先级的任何其他信息。

【讨论】:

  • 我可以用这些信息创建一个表,这不是问题。如果我这样做,那么需要什么查询
  • 非常好 - 如果 customer_priority 表中不存在任何行会发生什么情况 - 有时可能会出现这种情况
  • 您可以简单地插入具有默认值的记录。或者您将JOIN customer_priority 更改为LEFT OUTER JOIN customer_priority。在这种情况下,您可能还想将cp.priority_value 更改为coalesce(cp.priority_value, 99999) 之类的东西,以便将这些放在最后。
猜你喜欢
  • 2011-08-27
  • 2021-11-22
  • 2023-04-04
  • 2020-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多