Home > Net >  Query without using subquery/subselect
Query without using subquery/subselect

Time:11-22

I have 2 questions concerning re-writting queries, so that no subquery is needed.

  1. Is it - using Oracle-SQL-statements - possible to write one of the following queries without using any type of subquery (e.g. subselect)?
  2. If yes, how would this be possible.

Query #1 is as follows:

SELECT Stufe, (SELECT AVG(Stufe) FROM Charaktere) FROM Charaktere
WHERE Stufe > (SELECT AVG(Stufe) FROM Charaktere) ORDER BY Stufe DESC

Query #2 is as follows:

SELECT d.Name, (d.Lebenspunkte-e.Gruppenschaden) as Zustand FROM (
SELECT c.Name, k.Schwächen, (k.Basisleben * c.Leben_Multiplikator) as Lebenspunkte FROM Charaktere c
INNER JOIN Klassen k
ON c.Klasse = k.Klasse) d
INNER JOIN (
SELECT Klasse, SUM(Schaden) as Gruppenschaden FROM Charaktere
GROUP BY Klasse) e
ON d.Schwächen = e.Klasse
WHERE d.Lebenspunkte-e.Gruppenschaden > 0

Test data:

`

CREATE TABLE Charaktere (
    Charakter_ID varchar(300),
    Name varchar(300),
    Klasse varchar(300),
    Rasse varchar(300),
    Stufe varchar(300),
    Leben_Multiplikator varchar(300),
    Mana_Multiplikator varchar(300),
    Rüstung varchar(300),
    Waffen_ID varchar(300),
    Schaden varchar(300)
);

CREATE TABLE Klassen (
    Klassen_ID varchar(300),
    Klasse varchar(300),
    Basisleben varchar(300),
    Basismana varchar(300),
    Schwächen varchar(300)
);

CREATE TABLE Ausrüstung (
    Ausrüstung_ID varchar(300),
    Rüstung varchar(300),
    Schmuck varchar(300)
);

CREATE TABLE Waffen (
    Waffen_ID varchar(300),
    Links varchar(300),
    Rechts varchar(300)
);

INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('1','Herald','Zauberer','Mensch','67','2','8','Heilig','4','718');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('2','Roderic','Paladin','Mensch','55','10','3','Schwer','2','691');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('3','Favian','Schurke','Ork','32','4','1','Leicht','3','243');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('4','Vega','Berserker','Zwerg','44','9','8','Schwer','2','118');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('5','Matep','Jäger','Dunkel Elf','24','3','6','Leicht','1','368');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('6','Euris','Kleriker','Mensch','77','7','8','Resistent','4','774');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('7','Dara’a','Nekromant','Blut Elf','99','6','1','Verdorben','5','966');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('8','Eodriel','Magier','Hoch Elf','24','2','3','Resistent','5','399');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('9','Kerodan','Magier','Blut Elf','20','6','2','Heilig','4','758');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('10','Hans','Paladin','Mensch','67','7','9','Schwer','2','632');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('11','Falk','Berserker','Mensch','13','8','6','Leicht','2','149');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('12','Sethrak','Paladin','Ork','54','5','1','Schwer','3','657');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('13','Hozen','Kleriker','Zwerg','68','6','3','Heilig','4','710');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('14','Venthyr','Jäger','Dunkel Elf','23','4','7','Leicht','1','197');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('15','Stanford','Paladin','Mensch','56','3','7','Resistent','2','370');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('16','Celoevalin','Zauberer','Blut Elf','8','3','6','Heilig','4','383');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('17','Sylvar','Berserker','Hoch Elf','76','9','4','Verdorben','2','837');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('18','Kyrian','Zauberer','Zwerg','69','6','3','Heilig','5','756');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('19','Ithris','Kleriker','Dunkel Elf','88','9','6','Resistent','4','500');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('20','Diedrich','Magier','Mensch','1','2','2','Heilig','2','102');
INSERT INTO Charaktere (Charakter_ID,Name,Klasse,Rasse,Stufe,Leben_Multiplikator,Mana_Multiplikator,Rüstung,Waffen_ID,Schaden) VALUES ('21','Dar’mir','Jäger','Blut Elf','14','1','7','Leicht','1','150');

INSERT INTO Klassen (Klassen_ID,Klasse,Basisleben,Basismana,Schwächen) VALUES ('1','Zauberer','70','170','Paladin');
INSERT INTO Klassen (Klassen_ID,Klasse,Basisleben,Basismana,Schwächen) VALUES ('2','Paladin','150','110','Zauberer');
INSERT INTO Klassen (Klassen_ID,Klasse,Basisleben,Basismana,Schwächen) VALUES ('3','Schurke','100','100','Magier');
INSERT INTO Klassen (Klassen_ID,Klasse,Basisleben,Basismana,Schwächen) VALUES ('4','Berserker','200','80','Jäger');
INSERT INTO Klassen (Klassen_ID,Klasse,Basisleben,Basismana,Schwächen) VALUES ('5','Jäger','110','100','Schurke');
INSERT INTO Klassen (Klassen_ID,Klasse,Basisleben,Basismana,Schwächen) VALUES ('6','Kleriker','95','120','Nekromant');
INSERT INTO Klassen (Klassen_ID,Klasse,Basisleben,Basismana,Schwächen) VALUES ('7','Nekromant','50','200','Paladin');
INSERT INTO Klassen (Klassen_ID,Klasse,Basisleben,Basismana,Schwächen) VALUES ('8','Magier','85','150','Berserker');

INSERT INTO Ausrüstung (Ausrüstung_ID,Rüstung,Schmuck) VALUES ('1','Schwer','Kette');
INSERT INTO Ausrüstung (Ausrüstung_ID,Rüstung,Schmuck) VALUES ('2','Leicht','Armreif');
INSERT INTO Ausrüstung (Ausrüstung_ID,Rüstung,Schmuck) VALUES ('3','Resistent','Anhänger');
INSERT INTO Ausrüstung (Ausrüstung_ID,Rüstung,Schmuck) VALUES ('4','Heilig','Ring');
INSERT INTO Ausrüstung (Ausrüstung_ID,Rüstung,Schmuck) VALUES ('5','Verdorben','Talisman');

INSERT INTO Waffen (Waffen_ID,Links,Rechts) VALUES ('1','Bogen','Dolch');
INSERT INTO Waffen (Waffen_ID,Links,Rechts) VALUES ('2','Langschwert',NULL);
INSERT INTO Waffen (Waffen_ID,Links,Rechts) VALUES ('3','Axt','Axt');
INSERT INTO Waffen (Waffen_ID,Links,Rechts) VALUES ('4','Zauberstab','Zauberbuch');
INSERT INTO Waffen (Waffen_ID,Links,Rechts) VALUES ('5','Zauberbuch','Zauberbuch');

`

I already searched on StackOverflow but cannot re-write these two queries based on the provided information. I guess, the use of JOINS and/or GROUP BY would suffice, ...?

CodePudding user response:

You can use a CTE to make it bit more simple.

The first query can be rewritten as :

with cte as (SELECT AVG(Stufe) avg_Stufe FROM Charaktere) 
SELECT Stufe, cte.avg_Stufe
FROM Charaktere 
CROSS JOIN cte 
WHERE Stufe > cte.avg_Stufe 
ORDER BY Stufe DESC

And the second query can be rewritten as

with cte as (
  SELECT Klasse, SUM(Schaden) as Gruppenschaden  FROM Charaktere  GROUP BY Klasse) 
SELECT c.Name, (k.Basisleben * c.Leben_Multiplikator) - Gruppenschaden as Zustand 
FROM Charaktere c 
JOIN Klassen k ON c.Klasse = k.Klasse
JOIN cte ON (cte.Klasse = k.Schwächen)
WHERE (k.Basisleben * c.Leben_Multiplikator) - Gruppenschaden > 0

Without using CTE :

The above 2 queries can be rearranged to avoid the CTE

query 1:

SELECT c.Stufe, AVG(cte.Stufe) avg_Stufe
FROM Charaktere c
CROSS JOIN Charaktere cte 
GROUP BY c.Stufe,c.Charakter_ID
HAVING c.Stufe > AVG(cte.Stufe)
ORDER BY c.Stufe DESC

query 2 :

SELECT c.Name, (k.Basisleben * c.Leben_Multiplikator) - SUM(cte.Schaden) as Zustand 
FROM Charaktere c 
JOIN Klassen k ON c.Klasse = k.Klasse
JOIN Charaktere cte ON (cte.Klasse = k.Schwächen)
group by c.Name, k.Basisleben, c.Leben_Multiplikator
having (k.Basisleben * c.Leben_Multiplikator) - SUM(cte.Schaden) > 0

if you take a closer look, you can see the outer tables from the earlier queries are a joining table now.

CodePudding user response:

Well, CTE is a kind of subquery quote from docs
Common Table Expressions - To specify common table expressions, use a WITH clause that has one or more comma-separated subclauses. Each subclause provides a subquery that produces a result set, and associates a name with the subquery.
Your Query 1 could be coded without subquery like here:

SELECT 
  c0.Stufe,
  Avg(c1.Stufe)  "StufeAVG"
FROM Charaktere c0
LEFT JOIN Charaktere c1 ON(1=1)
GROUP BY c0.Stufe, c0.CHARAKTER_ID
HAVING AVG(c1.Stufe) < c0.Stufe
ORDER BY c0.Stufe DESC
--  
--  R e s u l t :
--
--  Stufe                                    StufeAVG
--  -----   -----------------------------------------   
--     99   46.61904761904761904761904761904761904762
--     88   46.61904761904761904761904761904761904762
--     77   46.61904761904761904761904761904761904762
--     76   46.61904761904761904761904761904761904762
--     69   46.61904761904761904761904761904761904762
--     68   46.61904761904761904761904761904761904762
--     67   46.61904761904761904761904761904761904762
--     67   46.61904761904761904761904761904761904762
--     56   46.61904761904761904761904761904761904762
--     55   46.61904761904761904761904761904761904762
--     54   46.61904761904761904761904761904761904762

... not sure about the Query 2 but will try to figure it out. Maybe...

Query 2 without subqueries:

SELECT DISTINCT
    c.Name,
    (k.Basisleben * c.Leben_Multiplikator) - Sum(c1.Schaden) "Zustand"
FROM 
    Charaktere c
LEFT JOIN 
    Klassen k ON(c.Klasse = k.Klasse)
LEFT JOIN
    Charaktere c1 ON(c1.Klasse = k.Schwächen)
GROUP BY c.Name, (k.Basisleben * c.Leben_Multiplikator)
HAVING (k.Basisleben * c.Leben_Multiplikator) - Sum(c1.Schaden) > 0
--
--  R e s u l t :
--
--  Name    Zustand
--  ------- -------
--  Sylvar     1085
--  Vega       1085
--  Falk        885
--  Venthyr     197
--  Matep        87

Regards...

  • Related