Eine order-by
in einer Unterabfrage ist nicht nützlich, es sei denn, Sie filtern das Ergebnis nach rownum (und manchmal wird je nach Kontext ein Fehler). Und Sie können die innere Unterabfrage mit einem Ersatz kommen:
SELECT COUNT(*)
FROM (
SELECT DISTINCT a.col,b.colx,c.coly
FROM a
JOIN b on a.id = b.id
JOIN c on b.id = c.id
JOIN cwa on c.id cwa.cid
WHERE a.xyz = 'something'
AND b.hijk = 'something else'
AND cwa.csid = 22921
);
Sie könnten es sogar tun, ohne eine Unterabfrage, wenn Sie ein Zeichen identifizieren, die nicht in eine der drei Spalten angezeigt werden Sie die Auswahl, so dass Sie kann es als Trennzeichen verwenden; z.B. wenn Sie nie eine Tilde haben könnten Sie tun:
SELECT COUNT(DISTINCT a.col ||'~'|| b.colx ||'~'|| c.coly)
FROM a
JOIN b on a.id = b.id
JOIN c on b.id = c.id
JOIN cwa on c.id cwa.cid
WHERE a.xyz = 'something'
AND b.hijk = 'something else'
AND cwa.csid = 22921;
obwohl, ob die einfache oder klare Ansichtssache ist.
Als count()
nur ein einziges Argument nimmt, und Sie möchten die (unterschiedlichen) Kombinationen dieser drei Spalten zählen, verkettet dieser Mechanismus alle drei in einem einzelnen String und zählt dann Erscheinungen dieser Zeichenfolge. Das Trennzeichen hinzugefügt wird, so dass Sie zwischen mehrdeutigen Spaltenwerten, beispielsweise mit einem konstruiertes Beispiel in einem WAK unterscheiden:
with cte (col1, col2) as (
select 'The', 'search' from dual
union all select 'These', 'arch' from dual
)
select col1, col2,
col1 || col2 as bad,
col1 ||'~'|| col2 as good
from cte;
COL1 COL2 BAD GOOD
----- ------ ----------- ------------
The search Thesearch The~search
These arch Thesearch These~arch
Mit einfacher ‚schlechter‘ Verkettung beiden Reihen erscheinen gleich; durch die Begrenzer Hinzufügen die ‚gute‘ Version, damit Sie sich immer noch zwischen ihnen unterscheiden können, so zählen verschiedene concatenate Werte bekommt die richtige Antwort:
with cte (col1, col2) as (
select 'The', 'search' from dual
union all select 'These', 'arch' from dual
)
select count(distinct col1 || col2) as bad_count,
count (distinct col1 ||'~'|| col2) as good_count
from cte;
BAD_COUNT GOOD_COUNT
---------- ----------
1 2
Wenn col1
mit einer Tilde beendet oder col2
mit einer Tilde gestartet, Sie Würd zu Mehrdeutigkeit sein:
with cte (col1, col2) as (
select 'The~', 'search' from dual
union all select 'The', '~search' from dual
)
select col1, col2,
col1 || col2 as bad,
col1 ||'~'|| col2 as still_bad
from cte;
COL1 COL2 BAD STILL_BAD
---- ------- ----------- ------------
The~ search The~search The~~search
The ~search The~search The~~search
so muss der Begrenzer etwas sein, werden Sie nicht in irgendwelchen Werten finden.
Hint erhöhen: Durch die Bestellung kann entfernt werden; Außerdem benötigen Sie keine Abfrage über eine Abfrage – Aleksej