Prośba o sprawdzenie poprawnosci zapytania

0

mam takie zadanie:

  1.        Wypisz jakie usługi dla kontraktów 2,3 i 4 były aktywne w 2001-07-02.
    

Oczywiście już je zrobiłam :), mam tylko prośbę o sprawdzenie

select  k.KONTRAKT_ID, u.USLUGA_ID,u.SEQNO, u.DATA_ZM, u.STATUS from USLUGI u
    INNER JOIN  KONTRAKTY k on u.USLUGA_ID=k.KONTRAKT_ID
       where  u.DATA_ZM=TO_DATE('2001/07/02','yyyy/mm/dd') and u.STATUS='a'
HAVING  k.KONTRAKT_ID < 5 and  k.KONTRAKT_ID > 1
GROUP BY u.USLUGA_ID, u.SEQNO , u.DATA_ZM, u.STATUS, k.KONTRAKT_ID;

wynik tego zapytania jest pod linkiem:
bulicka.ugu.pl/wynik.png

Cała struktura tabel i wypełniania przedstawia się następująco:

CREATE TABLE KONTRAKTY
(
  KONTRAKT_ID  NUMBER(10),
  GRUPA_ID     NUMBER(4)
)
LOGGING 
NOCACHE
NOPARALLEL;


declare i number;
		j number;
		k number;

begin
i:=0;
for i in 1 .. 10000 loop
	j:=dbms_random.value(1,100);
	k:=0;
	if j<20 then k:=1 ; end if;
	if j>=20 and j<60 then k:=2 ; end if;
	if j>=60 and j<63 then k:=3 ; end if;
	if j>=63 then k:=4 ; end if;
insert into kontrakty values 
(
 	   i,
	   k);
end loop;
commit;
end;
/

CREATE INDEX GR_IND ON KONTRAKTY
(GRUPA_ID)
LOGGING
NOPARALLEL;


CREATE UNIQUE INDEX PK_KONTRAKTY ON KONTRAKTY
(KONTRAKT_ID)
LOGGING
NOPARALLEL;


ALTER TABLE KONTRAKTY ADD (
  CONSTRAINT PK_KONTRAKTY PRIMARY KEY (KONTRAKT_ID));


CREATE TABLE ROZMOWY
(
  KONTRAKT_ID         NUMBER(10),
  DLUGOSC_POLACZENIA  NUMBER(16)
)
LOGGING 
NOCACHE
NOPARALLEL;


CREATE INDEX I_KTR_ID ON ROZMOWY
(KONTRAKT_ID)
LOGGING
NOPARALLEL;


truncate table rozmowy;

declare j number;
		k number;

begin
for ii in 1 .. 100 loop
	for i in 1 .. 1000 loop
				j:=dbms_random.value(1,10000);
				k:=dbms_random.value(1,1200);
				insert into rozmowy values (j,k);
	end loop;
	commit;
end loop;
end;
/


CREATE TABLE USLUGI
(
  KONTRAKT_ID  NUMBER(10),
  USLUGA_ID     NUMBER(4),
  SEQNO			NUMBER(4),
  DATA_ZM		DATE,
  STATUS		VARCHAR(1)
);

truncate table uslugi;

declare j number;
		k number;
		u number;
		sq number;
		d1 number;
		dt date;
		dt2 date;
		st number;
		us_n number;

BEGIN
   dt := TO_DATE ('2000-01-01', 'YYYY-MM-DD');
   FOR j IN 1 .. 10000
   LOOP
	   u:=1;
	   d1 := TRUNC (DBMS_RANDOM.VALUE (1, 1300));
	   sq := TRUNC (DBMS_RANDOM.VALUE (1, 4));
	   dt2 := dt + d1;
	   k :=0;
	   us_n := TRUNC (DBMS_RANDOM.VALUE (1, 20));
	   FOR i IN 1 .. us_n
	   LOOP
		  k := TRUNC (DBMS_RANDOM.VALUE (1, 10));
	      --sys.dbms_output.put_line(to_char(dt2,'YYYY-MM-DD'));
	      INSERT INTO uslugi
	           VALUES (j, u , 0, dt2, 'a');
		  if sq>1 then 
		      INSERT INTO uslugi
		           VALUES (j, u , 1, dt2+k, 'd');
			  if sq>2 then 
			      INSERT INTO uslugi
		           VALUES (j, u , 2, dt2+2*k, 'a');
		      end if;
		  end if;
	      u:=u+k;
	   END LOOP;
   END LOOP;
   COMMIT;
END;
/ 

wynik zapytania select tabel USLUGI i KONTRAKTY przedstawia się na rys dostępnym pod linkiem:

bulicka.ugu.pl/sql.png

Wydaje mi się że dobrze zrobiłam, ale wole się zapytać na pewno czy jest dobrze ... Proszę uprzejmie o wskazówkę jeśli, że wykonałam zapytanie

0

generalnie zwraca to co miało, ale jest to nieoptymalne, zakręcone i generalnie nie tak :p

SELECT 
  kontrakt_id,
  uslugs_id,
  seqno,
  status
FROM
  uslugi
WHERE
  kontrakt_id IN (2, 3, 4) --tak ponieważ w zadaniu są wyszczególnione konkretne id a nie np. od 2 do 4
  AND data_zam = TO_DATE('2001/07/02','yyyy/mm/dd')

no i w zadaniu nic nie ma o statusie (że ma być = a)

0

poprawiłam na tak:

SELECT  
  k.KONTRAKT_ID, u.USLUGA_ID,u.SEQNO, u.DATA_ZM, u.STATUS from USLUGI u
INNER JOIN  KONTRAKTY k 
  on u.USLUGA_ID=k.KONTRAKT_ID
WHERE 
  u.DATA_ZM=TO_DATE('2001/07/02','yyyy/mm/dd') and u.STATUS='a' and
  k.kontrakt_id IN (2, 3, 4)
GROUP BY 
  u.USLUGA_ID, u.SEQNO , u.DATA_ZM, u.STATUS, k.KONTRAKT_ID;

**DZIĘKUJE SERDECZNIE **ZA WSKAZÓWKI :) :) :)

0

zapytam się jeszcze coś :)
jak wypisać wszystkie usługi, dla kontraktu, mającego aktualnie najwięcej włączonych usług.

Zaczęłam robić tak:

select 
   KONTRAKT_ID,  count(USLUGA_ID)
from 
   USLUGI 
where 
   status='a'
group BY 
   KONTRAKT_ID 
order by 
    KONTRAKT_ID ASC

policzyło mi ale nie wiem jak wybrać z tego max liczbę :( ?

a jak robię w ten sposób:

select  max(cnt) from
( select KONTRAKT_ID k, count(USLUGA_ID) cnt
  from USLUGI
  where status='a'
  group by KONTRAKT_ID
)

to nie wiem jak podać, który kontrakt ma najwięcej usług ?

nie wiem też czy dodawać też inner join . Jesli mam tylko zaznaczone, że rekord jest kluczem obcym, ale nie jest połączony relacja z drugą tabela. Jeśli nie jest połączony relacja z drugą tabela to chyba inner join nie jest potrzeby?


ALTER TABLE KONTRAKTY ADD (
  CONSTRAINT PK_KONTRAKTY PRIMARY KEY (KONTRAKT_ID));

Proszę uprzejmie o wskazówkę . W 1 pytaniu dotyczącym max wartości, próbowałam przez HAVING ale nie działało :(

0

oki już chyba zrobiłam :)

SELECT a.KONTRAKT_ID, count(*) 
         FROM USLUGI a
         WHERE a.status='a'
         GROUP BY a.KONTRAKT_ID 
         HAVING count(*) = (SELECT MAX(count(*)) 
                         FROM USLUGI b
                         where b.status='a'
                         GROUP BY b.KONTRAKT_ID)

:) :) :) :) :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1