如何将我的查询结果显示为字符串的一部分?

Posted

技术标签:

【中文标题】如何将我的查询结果显示为字符串的一部分?【英文标题】:How do I display my query results as part of a string? 【发布时间】:2019-08-20 18:23:57 【问题描述】:

我的数据库用于一个学校项目,并处理由顾问管理的各种工作/合同。抱歉,如果上下文含糊不清,我们也没有真正得到太多。

我当前的代码按照预期执行,它选择了领导最多合同/工作的顾问的名字和姓氏。但是我需要以特定格式显示结果。

SELECT DISTINCT CONSULTANT_FNAME, CONSULTANT_SNAME
FROM CONSULTANT LEFT JOIN CONTRACT ON CONSULTANT_ID = CONTRACT_LEAD
WHERE CONTRACT_LEAD IN(
SELECT CONTRACT_LEAD
FROM CONTRACT
GROUP BY CONTRACT_LEAD
ORDER BY COUNT(CONTRACT_LEAD) DESC
FETCH NEXT 1 ROWS ONLY);

目前我得到的结果是:

CONSULTANT_FNAME     CONSULTANT_SNAME
-------------------- --------------------
Cloud                Strife

但是我需要将结果显示为“领导最多合同的顾问是:Cloud Strife”。

【问题讨论】:

提示:CONCAT(). 【参考方案1】:

您不应该需要 DISTINCT - 您只需要将它放在那里,因为 LEFT JOIN 会导致顾问行重复(每个顾问有多个合同),但您也不需要左连接

SELECT 
  'The consultant who has led the most contracts is: ' || CONSULTANT_FNAME || ' ' || CONSULTANT_SNAME
FROM CONSULTANT 
WHERE CONSULTANT_ID IN(
  SELECT CONTRACT_LEAD
  FROM CONTRACT
  GROUP BY CONTRACT_LEAD
  ORDER BY COUNT(CONTRACT_LEAD) DESC
  FETCH NEXT 1 ROWS ONLY
)

IN 中的子查询返回最活跃的合同线索 id,但这与顾问 id 相同——您不需要加入。

我相信你也可以这样做:

SELECT 
  'The consultant who has led the most contracts is: ' || CONSULTANT_FNAME || ' ' || CONSULTANT_SNAME
FROM 
  CONSULTANT 
  INNER JOIN CONTRACT ON CONSULTANT_ID = CONTRACT_LEAD
GROUP BY CONSULTANT_FNAME, CONSULTANT_SNAME
ORDER BY COUNT(*) DESC
FETCH NEXT 1 ROWS ONLY

之所以有效,是因为 name 分组实际上与 id 分组相同:它计算合约表导致重复的次数。虽然这有一个轻微的错误风险,但如果真的有两个同名的不同人,他们会将他们的合同添加到一起。为了解决这个问题,您可以将 advisor_id 添加到 group by - 如果您正在执行 group by 则您不能使用 SELECT 区域中未在 group by 中提及的列(除非您将它们放在聚合函数中,例如 min、max等)但您可以将列放在组中,然后您不会在选择中使用。通过添加 ID 我们提供了一种方法来告诉两位同名顾问不要将他们的分数相加:

SELECT 
  'The consultant who has led the most contracts is: ' || s.CONSULTANT_FNAME || ' ' || s.CONSULTANT_SNAME
FROM 
  CONSULTANT s
  INNER JOIN CONTRACT t ON s.CONSULTANT_ID = t.CONTRACT_LEAD
GROUP BY s.CONSULTANT_FNAME, s.CONSULTANT_SNAME, s.CONSULTANT_ID
ORDER BY COUNT(*) DESC
FETCH NEXT 1 ROWS ONLY

这里是最后的学习点;总是给你的表起别名(我使用了 s 和 t)并使用别名。如果有人将新列添加到例如也称为 CONSULTANT_FNAME 的合同中,这可以防止您的查询停止工作 - 如果没有别名,您的查询将仅在列名明确且数据库架构随时间发生变化时才有效

添加表别名还可以让您将一个表加入两次,这在例如顾问有一个 home_address_id 和一个 work_address_id,它们映射到地址表中的两个不同行。如果您只使用home_address_id = address.id OR work_address_id = address.id 将地址加入一次,那么当数据更适合用作一行时,您最终会得到两行。 sql 101 到此结束 :) 但如果您对此信息块有更多疑问,请参阅When to use SQL Table Alias

【讨论】:

感谢您对如何改进我的代码的回复和建议,我对 SQL 还是很陌生。但是,两个查询都返回此错误消息:第 2 行出现错误:ORA-00909:参数数量无效 啊,我猜 oracle 还没有赶上世界其他地方提供的 CONCAT 版本,它接受 N 个参数并将它们连接在一起 - 换成专有的 ||字符串连接形式。 Oracle 的 concat 只需要一对,这意味着它必须重复链接,这会使查询变得混乱。有趣的;当我第一次看时,我可以发誓这不是一个预言的问题 值得记住 CONCAT 以备不时之需,但如果您使用的是非 oracle - 在其他 dbms 中,它通常是比 + 之类的更有用的连接字符串的方法,因为对于 SQL Server,如果您的string Concat 为空,如果使用 + 则整个字符串变为空,但如果使用 concat() 函数则不会。在 oracle 中,我们没有 string||null 导致 null【参考方案2】:

您可以使用以下查询 -

SELECT DISTINCT 'The consultant who has led the most contracts is: ' || CONSULTANT_FNAME || ' ' || CONSULTANT_SNAME
FROM CONSULTANT LEFT JOIN CONTRACT ON CONSULTANT_ID = CONTRACT_LEAD
WHERE CONTRACT_LEAD IN(SELECT CONTRACT_LEAD
                       FROM CONTRACT
                       GROUP BY CONTRACT_LEAD
                       ORDER BY COUNT(CONTRACT_LEAD) DESC
                       FETCH NEXT 1 ROWS ONLY);

【讨论】:

感谢您的回复!不幸的是,我收到了这个错误:第 1 行的错误:ORA-00909:无效的参数数量 @N26916,这是 Oracle 错误,您已经标记了有问题的 mysql。您实际上使用的是哪个 DBMS? Oracle 或 MySQL。

以上是关于如何将我的查询结果显示为字符串的一部分?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 `fetch` 将我的 JSON 字符串转换为查询字符串?副作用? [复制]

MySQL查询结果中显示数据类型?

如何将我的列表转换为字符串?

如何将我的十六进制字符串转换为数字? [复制]

将我的 mssql 查询变成结构化的 xml 结果集

如何使用 &nbsp 元素将我的字符串解析为 XML?