我正在尝试使用以下条件从Oracle数据库表中检索数据
为了满足上述条件,我编写了如下的查询
SELECT DISTINCT ba.uuid AS uuid
, COUNT(*) over() AS rowcount
FROM basicaddress ba
WHERE ba.postalcode='143456'
OR ba.lastname LIKE '%143456%'
OR ba.city LIKE '%143456%'
GROUP BY
CASE WHEN ba.postalcode='143456' THEN ba.postalcode END
ORDER BY
CASE WHEN ba.postalcode='143456' THEN ba.postalcode END DESC,
CASE WHEN ba.lastname LIKE '%143456%' THEN ba.lastname END ASC,
CASE WHEN ba.city LIKE '%143456%' THEN ba.city ELSE ba.postalcode END DESC
此查询在MYSQL中正常工作,但在oracle中它表示“不是GROUP BY表达式”
非常感谢任何帮助
答案 0 :(得分:1)
这只是因为MySQL打破了SQL的逻辑。
假设我们有表emp:
id ename dept
1 mark 10
2 John 10
3 Mary 10
4 Jane 20
和查询:
select dept, ename
from emp
group by dept;
你会得到什么?
你应该得到两行,因为有两个部门,但查询要求ename。对于20是明确的但是10发动机应该返回什么?
它会返回一个错误。猜不出要给予什么。 Oracle发出错误 - 你的错误,但是MySQL得到了一个ename(不保证是哪个)。 这是误导性的,可能会导致错误。
正确的查询将是:
select dept, max(ename) --the latest, alaphabeticaly
from emp
group by dept;
和
--all enames and groups
select dept, ename
from emp
group by dept, ename;
更正此部分后,您必须解决
COUNT(*) over() AS rowcount
一部分。在oracle,AFAIK中,您不能通过查询将分析函数与group混合。
答案 1 :(得分:1)
您问题的具体答案是uuid
未按表达式包含在组中。其他答案已经解释了允许这种情况发生的MySQL(mis)功能。修复查询很简单:
SELECT ba.uuid AS uuid, COUNT(*) over() AS rowcount
FROM basicaddress ba
WHERE ba.postalcode='143456' OR ba.lastname LIKE '%143456%' OR ba.city LIKE '%143456%'
GROUP BY uuid,
CASE WHEN ba.postalcode='143456' THEN ba.postalcode END
ORDER BY
max(CASE WHEN ba.postalcode='143456' THEN ba.postalcode END) DESC,
max(CASE WHEN ba.lastname LIKE '%143456%' THEN ba.lastname END) ASC,
max(CASE WHEN ba.city LIKE '%143456%' THEN ba.city ELSE ba.postalcode END)
我还删除了使用group by时应该是多余的“distinct”。
那就是说,我看不出这是如何满足你原来的问题的。我期待更多的内容如下:
select (case when postalcode is not null then postalcode
when city is not null then city
when lastname is not null then lastname
end),
(case when postalcode is not null then 1
when city is not null then 2
when lastname is not null then 3
end),
count(*)
from basicaddress ba
group by (case when postalcode is not null then postalcode
when city is not null then city
when lastname is not null then lastname
end),
(case when postalcode is not null then 1
when city is not null then 2
when lastname is not null then 3
end)
order by 1, 2
这可能不是您所需要的,但它应该指向正确的方向。此外,这是标准SQL,可以在两个数据库中使用。
答案 2 :(得分:0)
它适用于MySQl,因为MySQL对SQL有一种粗略的解释。
在任何正确的方言中,SELECT
或ORDER BY
子句中的任何内容都必须是聚合函数或GROUPed表达式。
至少,你需要按ba.uuid,姓氏和城市进行分组。
答案 3 :(得分:0)
我不了解MySQL,但以下是在Oracle 11g中运行的:
With
T_PATTERN as (select '%143456%' as PATTERN from DUAL)
, T_INPUT as (
select 1 as UUID, 'X143456y' as FIRSTNAME, 'last1' as LASTNAME, 'u143456v' as CITY, 'w143456z' as POSTALCODE from DUAL union
select 2 as UUID, 'first2' as FIRSTNAME, 'a143456b' as LASTNAME, 'a143456b' as CITY, 'postal2' as POSTALCODE from DUAL union
select 3 as UUID, 'first3' as FIRSTNAME, 'last3' as LASTNAME, 'c143456d' as CITY, 'postal3' as POSTALCODE from DUAL union
select 4 as UUID, 'first4' as FIRSTNAME, 'last4' as LASTNAME, 'city4' as CITY, 'postal4' as POSTALCODE from DUAL
),
Q_FNAME as (
select TI.UUID, TI.FIRSTNAME, COUNT(*) FN_COUNT from T_INPUT TI inner join T_PATTERN TP on 1=1
where UPPER(TI.FIRSTNAME) like TP.PATTERN
GROUP BY TI.UUID, TI.FIRSTNAME
),
Q_LNAME as (
select TI.UUID, TI.LASTNAME, COUNT(*) LN_COUNT from T_INPUT TI inner join T_PATTERN TP on 1=1
where UPPER(TI.LASTNAME) like TP.PATTERN
group by TI.UUID, TI.LASTNAME
),
Q_CITY as (
select TI.UUID, TI.CITY, COUNT(*) CT_COUNT from T_INPUT TI inner join T_PATTERN TP on 1=1
where UPPER(TI.CITY) like TP.PATTERN
group by TI.UUID, TI.CITY
),
Q_PCODE as (
select TI.UUID, TI.POSTALCODE, COUNT(*) PC_COUNT from T_INPUT TI inner join T_PATTERN TP on 1=1
where UPPER(TI.POSTALCODE) like TP.PATTERN
group by TI.UUID, TI.POSTALCODE
)
select TI.UUID, TI.FIRSTNAME, TI.LASTNAME, TI.CITY, TI.POSTALCODE,
QF.FN_COUNT, QL.LN_COUNT, QC.CT_COUNT, QP.PC_COUNT
from T_INPUT ti
left join Q_FNAME QF on TI.UUID=QF.UUID
left join Q_LNAME QL on TI.UUID=QL.UUID
left join Q_CITY QC on TI.UUID=QC.UUID
left join Q_PCODE QP on TI.UUID=QP.UUID
order by ti.UUID;