2016-05-12 10 views
0

ich dies nicht zur Arbeit bekommen, tut mir leid, wenn es zu einfach scheint, aber ich freue mich wirklich für Anregungen:Oracle - nicht das gewünschte Ergebnis zu erzielen

Ich habe 3 Tabellen:

UNFÄLLE

(
ACCIDENT_DATE DATE, 
DRIVER_CODE VARCHAR2, 
DAMAGES NUMBER, 
LOCATION_ACCIDENT VARCHAR2, 
CAR_CODE VARCHAR2 
) 

CARS

(
CAR_CODE VARCHAR2, 
MODEL VARCHAR2, 
YEAR VARCHAR2, 
CODE_OWNER VARCHAR2) 
// I didn't use this table ,but it was stated so I didn't want to miss anything 

PERSON

(
CODE VARCHAR2, 
NAME VARCHAR2, 
RESIDENCE VARCHAR2 
) 

Die Abfrage ist:
Display der Name und der Code der Personen, die in den letzten 4 Monaten mehr als zwei Unfälle hatte

ich geschrieben habe:

select a.driver_code,a.accident_date,p.name 
from accidents a join p person 
on (a.driver_code=p.code) 
group by a.accident_date,a.driver_code,p.code 
having count (a.accident_date)>2 

Es zeigt 1 von 2 Fahrern, die mehr als 2 Unfälle hatten, aber nachdem ich mit meinen Tabellendaten herumgespielt hatte, hieß es, dass sie überhaupt Daten finden könnten.

Ich weiß, dass ich es für die letzten 4 Monate Teil nicht aufgelöst habe, weil ich nicht sicher bin, wie man es benutzt. Das ist meine Idee, obwohl ich weiß, dass dies die Monate zwischen dem Datum des Systems und dem Datum des Unfalls (alle von ihnen) anzeigen (oder annehmen wird), während ich die Treiber in den letzten 4 Monaten anzeigen sollte:

select a.driver_code,a.accident_date,p.name, 
    sysdate,accident_date, 
    months_between(sysdate,accident_date) 
    from accidents a join p person 
    on (a.driver_code=p.code) 
    group by a.accident_date,a.driver_code,p.code 
    having count (a.accident_date)>2 
+1

Die allgemeine GROUP geben BY Regel besagt: Wenn eine GROUP BY-Klausel angegeben ist, muss jede Spaltenreferenz in der SELECT-Liste entweder eine Gruppierungsspalte identifizieren oder das Argument einer SET-Funktion sein! – jarlh

Antwort

2

Sie so etwas wie dieses benötigen:

select a.driver_code, p.name 
from accidents a 
    inner join p person 
    on (a.driver_code=p.code) 
where accident_date >= add_months(sysdate, -4) 
group by a.driver_code, p.name 
having count (1)>2 

auf diese Weise können nur die Unfälle in den letzten 4 Monaten prüfen, dann zählen die Unfälle pro Benutzer und fügen Sie nur eine weitere Bedingung, die Benutzer abrufen mit mindestens 2 Unfälle.

+0

Ich habe eine Frage, sollte es nicht sein: wo a.accident_date> = add_months (sysdate, -4) und auch a.accident_date zur Auswahl hinzufügen; und in der having-Klausel kann 1 den Platz von a.accident_date einnehmen? – AIP

+0

Es ist nicht notwendig, 'a. vor' zu unfall_datum 'hinzuzufügen, weil Sie nur diese Spalte in der Tabelle 'Unfälle' haben, so dass Sie keine Mehrdeutigkeiten haben; Wenn Sie 'accident_date' in der Auswahlliste hinzugefügt haben, müssen Sie sie sogar in der 'group by'-Klausel hinzufügen, so dass für jedes Datum eine Zeile und nicht eine Zeile pro Treiber vorhanden ist. In einem 'count()' können Sie einen Wert von 1 oder was auch immer nicht null verwenden, um sicherzustellen, dass alle Zeilen gezählt werden, unabhängig von den Feldern. Anders gesagt, wenn Sie 'count (someField)' setzen, haben Sie nur die Anzahl der Zeilen, in denen 'someField nicht null 'ist, nicht alle Zeilen – Aleksej

-1

Getestet habe ich diese auf Microsoft SQL Server, sollte aber unverändert auf Oracle laufen:

create table ACCIDENTS (
    ACCIDENT_DATE DATETIME , 
    DRIVER_CODE NVARCHAR(10) , 
    DAMAGES DECIMAL, 
    LOCATION_ACCIDENT NVARCHAR(100), 
    CAR_CODE NVARCHAR(10) 
) 


create table CARS (
    CAR_CODE NVARCHAR(10), 
    MODEL NVARCHAR(10), 
    YEAR NVARCHAR(10), 
    CODE_OWNER NVARCHAR(10) 
) 

insert into cars values ('THX1138','Ford Orion','2005','J.Taylor') 
insert into cars values ('BHQ1142','Ford Ka','1980','J. Caesar') 


insert into accidents values ('2015-09-17','JT',345.0,'Warsaw','THX1138') 
insert into accidents values ('2015-09-18','JT',222.0,'Warsaw','THX1138') 
insert into accidents values ('2015-09-20','JC',444.0,'London','BHQ1142') 


with numberOfAccidents as (
    select driver_code, count(driver_code) as numberOfAccidents from accidents group by driver_code 
) 

select a.driver_code,a.accident_date 
from accidents a 
where driver_code In (select driver_code from numberOfAccidents where numberOfAccidents >= 2) 

Sie mit einer where-Klausel auf die hinzufügen können Unfälle in den letzten 4 Monaten

Verwandte Themen