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