Jeg kender ikke noget til Oracle, men da det lyder som noget der er temmelig standard SQL, vil jeg da gerne gøre et forsøg...
Start med at oprette en tabel med årstal:
CREATE TABLE MEDARB.ÅRSTAL (ÅR DEC (4 , 0) NOT NULL WITH DEFAULT)
Fyld så nogle data i tabellen:
INSERT INTO MEDARB.ÅRSTAL VALUES(1995) INSERT INTO MEDARB.ÅRSTAL VALUES(1996) INSERT INTO MEDARB.ÅRSTAL VALUES(1997) INSERT INTO MEDARB.ÅRSTAL VALUES(1998) INSERT INTO MEDARB.ÅRSTAL VALUES(1999) INSERT INTO MEDARB.ÅRSTAL VALUES(2000) INSERT INTO MEDARB.ÅRSTAL VALUES(2001) INSERT INTO MEDARB.ÅRSTAL VALUES(2002) INSERT INTO MEDARB.ÅRSTAL VALUES(2003) INSERT INTO MEDARB.ÅRSTAL VALUES(2004) INSERT INTO MEDARB.ÅRSTAL VALUES(2005) INSERT INTO MEDARB.ÅRSTAL VALUES(2006) INSERT INTO MEDARB.ÅRSTAL VALUES(2007) INSERT INTO MEDARB.ÅRSTAL VALUES(2008) INSERT INTO MEDARB.ÅRSTAL VALUES(2009) INSERT INTO MEDARB.ÅRSTAL VALUES(2010)
Nu er du så klar til at forsøge dig med en forespørgsel:
SELECT ÅRSTAL.ÅR, SUM(CASE WHEN YEAR(MEDARB.STARTDATO) <= ÅRSTAL.ÅR AND (MEDARB.STOPDATO IS NULL OR YEAR(MEDARB.STOPDATO) >= ÅRSTAL.ÅR)THEN 1 ELSE 0 END) AS ANSATTE FROM MEDARB.ÅRSTAL, MEDARB.MEDARBEJDERE AS MEDARB WHERE ÅRSTAL.ÅR <= YEAR(CURDATE()) GROUP BY ÅRSTAL.ÅR ORDER BY ÅRSTAL.ÅR
Eller alternativt kan man bruge en lidt anden syntax:
SELECT ÅRSTAL.ÅR, SUM(CASE WHEN YEAR(MEDARB.STARTDATO) <= ÅRSTAL.ÅR AND (MEDARB.STOPDATO IS NULL OR YEAR(MEDARB.STOPDATO) >= ÅRSTAL.ÅR)THEN 1 ELSE 0 END) AS ANSATTE FROM MEDARB.ÅRSTAL CROSS JOIN MEDARB.MEDARBEJDERE AS MEDARB WHERE ÅRSTAL.ÅR <= YEAR(CURDATE()) GROUP BY ÅRSTAL.ÅR ORDER BY ÅRSTAL.ÅR
Som sagt, så tror jeg også den vil virke på en Oracle database, da der er ikke er brugt specielle funktioner. Prøv den... :-)
Jeg har lige genlæst spørgsmålet, og er kommet lidt i tvivl om, hvorvidt jeg har misforstået det lidt. Derfor lige en tilføjelse:
SELECT ÅRSTAL.ÅR, SUM(CASE WHEN YEAR(MEDARB.STARTDATO) <= ÅRSTAL.ÅR AND (MEDARB.STOPDATO IS NULL OR YEAR(MEDARB.STOPDATO) >= ÅRSTAL.ÅR)THEN 1 ELSE 0 END) AS ANSATTE, SUM(CASE WHEN YEAR(MEDARB.STARTDATO) = ÅRSTAL.ÅR THEN 1 ELSE 0 END) AS NYANSATTE, SUM(CASE WHEN YEAR(MEDARB.STOPDATO) = ÅRSTAL.ÅR THEN 1 ELSE 0 END) AS STOPPEDEANSATTE FROM MEDARB.ÅRSTAL CROSS JOIN MEDARB.MEDARBEJDERE AS MEDARB WHERE ÅRSTAL.ÅR <= YEAR(CURDATE()) GROUP BY ÅRSTAL.ÅR ORDER BY ÅRSTAL.ÅR
Princippet er det samme. Der er bare tilføjet en optælling af, hvor mange der er hhv. startede og stoppede i årets løb.
Mit problem er, at jeg ikke har en tabel med årstal og egentligt ikke har beføjelser til at oprette sådan (skole projekt).
Jeg har 1 tabel der skal bruges:
medarbejdere (navn, startDato, slutDato)
Ikke mere...
Jeg har lavet lidt kode, hvor den beregner hvor mange ansatte der er hvert år, hvor der sker et skift i antallet - at en ny bliver ansat eller en gammel stopper. Men de år, hvor antallet er uændret bliver ikke repræsenteret... Tror min løsning er acceptabel men det kunne være rart med alle år i listen!
Jeg ved ikke om Oracle databasen har en funktion, som kan generere årstallene uden en egentlig tabel. Dertil kender jeg som sagt for lidt til denne database, men det er da ikke helt umuligt. Oracle er jo kendt for at have mange funktioner uden for standarderne. Jeg har ikke selv adgang til manualerne (de ligger ikke frit tilgængelige på Oracles site, som de gør på de fleste andre databaseproducenters), så jeg kan ikke umiddelbart komme på noget. Medmindre du kan "låne" fra en anden tabel, som du ved indeholder et numerisk felt med en ubrudt række af fortløbende tal. Så kan du jo trække på den i stedet og lægge til og trække fra, indtil du får den serie af årstal du ønsker. Ikke det mest elegante, men måske virker det jo for dig?...
CREATE TABLE employees ( id INTEGER PRIMARY KEY, name VARCHAR2(50), startdate DATE, enddate DATE );
INSERT INTO employees VALUES (1, 'Anders Andersen', '20020201', '20051031'); INSERT INTO employees VALUES (2, 'Børge Børgesen', '20040101', '20051031'); INSERT INTO employees VALUES (3, 'Christian Christensen', '20050101', '20051031');
query:
SELECT x.y,COUNT(*) FROM employees,(SELECT (SELECT MIN(TO_CHAR(startdate,'YYYY')) FROM employees)+ROWNUM-1 AS y FROM ALL_USERS,ALL_USERS WHERE ROWNUM <= (SELECT MAX(TO_CHAR(enddate,'YYYY'))-MIN(TO_CHAR(startdate,'YYYY'))+1 FROM employees)) x WHERE TO_CHAR(employees.startdate,'YYYY') <= x.y AND x.y <= TO_CHAR(employees.enddate,'YYYY') GROUP BY x.y;
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.