PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : SQL: Zeilen zählen



bionic
31-10-2005, 09:28
Hi miteinander,

Ich suche den SQL-Befehl um bei einer Oracle 9 Datenbank die Zeilen abzuzählen, weil ich dort leider kein AUTO_INCREMENT habe.

Der Befehl wird in einer Schleife ausgeführt und $counter wird immer um eins erhöht. Insgesamt passiert dies ca. 160'000 mal.

Das ganze sieht so aus:


SELECT VARIABLE WHERE ***BEFEHL*** = '$counter'

Habt ihr eine Idee, wie ich das machen könnte?

Danke,

bionic

ninguno
31-10-2005, 10:36
hab zwar keine ahnung was du genau willst bzw was dein select statement machen soll, aber ...

die anzahl der rows in der tabelle erhältst du so:
select count(*) from tabelle;

anzahl der rows die eine bedingung erfüllen:
select count(*) from tabelle where spalte1=123;

bionic
31-10-2005, 10:59
Danke für deine Antwort!

Mit COUNT(*) habe ich es auch bereits versucht... Ohne Erfolg.

Hier ist mein Code:

my $counter = "0";
while ($counter <= "159071")
{
my $sql= "SELECT WERT1 FROM TBL_1 WHERE ***BEFEHL für ZEILENNUMMER*** = '$counter' ";
my $sth = $dbh->prepare($sql) or die $dbh->errstr();
$sth->execute or die $dbh->errstr();
my $ursprungscode = $sth->fetchrow();

my $sql= "SELECT WERT1 FROM TBL_2 WHERE WERT1 = '$ursprungscode' ";
my $sth = $dbh->prepare($sql) or die $dbh->errstr();
my $targetcode = $sth->execute or die $dbh->errstr();
my $targetcode = $sth->fetchrow();

if ($ursprungscode ne $targetcode){
print $ursprungscode;
print "<br />";
$counter++;
}
}

Das gute Ding soll eigentlich nur die beiden Werte vergleichen und falls etwas nicht stimmt, soll $ursprungscode ausgegeben werden.

ninguno
31-10-2005, 11:21
:confused: kannst du bitte in worten erklären was das ganze soll. willst du für die ersten 159071 rows von tabelle 1 prüfen ob der selbe wert auch in tabelle 2 vorhanden ist??? wenn ja dann kann man das auch mit einem (=1) sql statement machen statt mit 2x159071 queries

bionic
31-10-2005, 11:31
Exakt das möchte ich machen.

Ich bin Anfänger auf dem Gebiet, eigentlich kann ich weder Perl noch SQL, deshalb bitte ich um ein bisschen Nachsicht, falls der Code "komisch" aussieht. ;-)

Wie würdest du dies in ein einziges SQL Statement packen?

Vielen Dank!

quinte17
31-10-2005, 12:28
hast du denn keinen key in deinen tabellen der gleich ist???
bitte suche mal nach einem guten sql-howto und lies darin die kapitel über joins
dann brauchst du noch wissen über gute datenbank strukturen (entity relationship diagramme sind dafür von nutzen)

greetz

ninguno
31-10-2005, 12:31
alle werte aus tabelle1 selektieren die nicht in tabelle2 enthalten sind:
SELECT WERT1 FROM TBL_1 t1
WHERE not exists (SELECT null FROM TBL_2 t2 WHERE t2.WERT1 = t1.wert1);

noch eine frage: willst du alle rows prüfen oder 159071 beliebige oder ... ?

bionic
31-10-2005, 14:12
@ninguno

Vielen Dank für den Code! Ich möchte gerne alle Werte überprüfen. Leider weiss ich nicht, ob das Script, das ich nun habe auch tatsächlich funktioniert. Vielleicht sind in den beiden Tabellen nämlich jeweils alle Werte vorhanden.

Ich brauche dieses Skript nur deshalb, weil das Tool, mit dem wir arbeiten, der Meinung war, dass in der zweiten Tabelle einige Einträge fehlen. Lasse ich das Skript nun laufen, dann gibt er für den Array keinen Wert aus. Ich gehe also davon aus, dass das Skript richtig ist und funktioniert. Falls ihr einen Fehler findet, wäre ich euch natürlich sehr dankbar, wenn ihr diesen mir mitteilt. Ansonsten Danke für alle Antworten und einen schönen Tag noch!


my $sql= "SELECT WERT1 FROM TBL_1 t1 WHERE not exists (SELECT null FROM TBL_2 t2 WHERE t2.WERT1 = t1.WERT1)";
my $sth = $dbh->prepare($sql) or die $dbh->errstr();
$sth->execute or die $dbh->errstr();

my @result = $sth->fetchrow_array();

print @result;

michael.sprick
31-10-2005, 14:45
weil ich dort leider kein AUTO_INCREMENT habe.
zwar nicht so, wie es in mysql implementiert ist, aber automatische Werte kann man auch mit Oracle erzeugen...
Da nennt man das dann sequences:


CREATE SEQUENCE SEQ1
START WITH 1
INCREMENT BY 1
NOMAXVALUE
NOCYCLE
CACHE 4;


Damit hast Du schonmal einen Zähler - benutzen kannst Du ihn so:



INSERT INTO <tabelle> (id, name) values (SEQ1.NEXTVAL, 'testname');


mit SEQ1.NEXTVAL kommst Du jeweils die nächste Nummer und inkrementierst den Zähler.
mit SEQ1.CURVAL kannst Du sie ein weiteres Mal abfragen, ohne den Zähler dabei zu erhöhen...

EDIT: Achja - Du kannst SEQ1.NEXTVAL natürlich auch als Default Value für eine Spalte definieren... wichtig ist nur, dass Du die Sequence vorher schon angelegt hast...

bionic
31-10-2005, 15:09
@ michael.sprick
Danke für deine Antwort. Leider sollte ich die DB nach Möglichkeit nicht verändern, d.h. ich sollte auch keine neuen Spalten erzeugen.

Ich habe nun mit einem anderen Script die Anzahl Zeilen verglichen und leider gibt es grosse Unterschiede. Mein oberes Skript funktionert also noch nicht und ich habe keine Ahnung, woran es liegt. Die Ausgabe ist immer nur "done." Stimmt etwas mit dem Array nicht? Denn das SQL sollte ja nun stimmen...

bionic
31-10-2005, 15:24
OK... Habe den Fehler gefunden! Der Array wurde falsch ausgegeben und alle Werte sind auch in der anderen table vorhanden.

Danke an alle, die mir bei dem Problem geholfen haben! (Coole Community!)

sticky bit
05-11-2005, 16:53
Ohne den Zweck der Aktion tatsächlich zu durchschauen, die Zeilennummer ist in der Pseudo-Spalte rownum enthalten:


SELECT col,
rownum
FROM tab;

Zum Vergleichen ist das aber wohl eher untauglich, da die Anordnung der Zeieln in der Tabelle unerheblich ist und das DBMS das anorden darf bei der Ausgabe wie es will (ausser bei nem ORDER BY, aber der würde erst nach dem rownum kommen)!

kehj
05-11-2005, 19:44
Darf ich mal fragen, wozu du die Zeilen vergleichen willst?
Eine Programmieraufgabe für Schule/Studium?

Ich schließe mich übrigens meinen Vorrednern an: es läßt sich viel einfacher über 'nen Join lösen