PDA

Ver la Versión Completa : Consulta Dificil


muli
26-10-2006, 20:54:19
Bueno consulta dificil para mi, facil para muchos, uso Firebird y tengo lo siguiente:
Una tabla maestra:
DNI,Nombre
Una Tabla Detalle: Enlace,modalidad

Las Tablas están unidas por los Campos(DNi-Enlace) existe Referencia de Integridad.

Lo que necesito es lo siguiente:
Necesito una Consulta SQL que me de todos aquellos registros de la tabla maestra que cumplan unas condiciones en la tabla detalle. Es decir, imaginense el siguiente cuadro:
uno pepe
uno Hogar
uno Auto
Dos Juan
Dos Hogar
Dos Accidente
Dos Auto
Tres OtroPepe
Tres Auto
Pues necesito aquella consulta por ejemplo que me quite todos aquellos clientes que tengan Hogar y Auto y no tenga Accidente.

Gracias.

Crandel
27-10-2006, 03:08:28
En realidad es una consulta facil, te recomendaria aprender un poco mas sobre SQL xq te va a tocar hacer consultas mas complicadas.

Un libro recomendable y gratuito es la La Cara oculta de Delphi 4 que se puede conseguir por internet desde la pagina del autor Ian marteens

Tu consulta seria:
Select * form MAESTRA, DETALLE
where DNI = ENLACE
and MODALIDAD = ...

muli
27-10-2006, 11:03:53
Pues yo te digo que no es tan facil, por que si hago esto:
SELECT * From Maestra Inner Join Detalle On Maestra.Indice=Detalle.Enlace
Where (Detalle.Producto=Modalidad And Detalle.Producto=OtraModalidad)
No Salen los registros clientes que tienen esas dos modalidades

P.D.: No hace falta que me recomiendes un libro antiguo, ya me he desembolsado la pasta en La Cara Oculta De Delphi 6 que está bastante mejor que el 4. Y un Delphi Original cosa que no pueden decir muchos, y si pido ayuda en el foro, es por que antes estuve revisando todos los mensajes del foro, ya que no pregunto por preguntar.

richi
27-10-2006, 11:37:10
Prueba de la siguiente forma.

Select * form MAESTRA M JOIN DETALLE D ON (M.DNI=D.ENLACE)
where MODALIDAD='Hogar' OR MODALIDAD='Auto'

Tanto hogar como auto mira en la base de datos si estas en mayusculas o minusculas en este caso buscaria los que tienen la primera letra en mayuscula y el resto en minusculas.

muli
27-10-2006, 13:55:22
De esas forma me salen todos aquellos registros que tengan Auto o Hogar no los que tengan auto y Hogar, pues si hay un cliente que tiene solamente Auto ya saldría, cuando no debería de salir.

Saludos

Lepe
27-10-2006, 14:20:43
De esta forma no lo veo muy complicado:

select * from maestra
where dni in (
select dni from detalle
where modalidad in (:incluir) and
modalidad not in (:noincluir)
)


He buscado la mejor forma para programarlo (no de ejecución). Yo suelo crear un StringList que tenga "Hogar" y "Auto" y con una simple rutina QuotedList, ya tengo lo que va entre paréntesis armado como si fuera un parámetro.


function QuotedList( Items: TStrings):string;
var i:integer;
begin
result := '';
for i:= 0 to Items.Count-2 do
Result := Result +QuotedStr(Items[i])+',';
if Items.count > 0 then
Result := Result + quotedstr(Items[Items.count-1]);
end;
Para armar la consulta:

var st:StringList;
begin
st := stringlist.Create;
st.add('Hogar');
st.Add('Auto');

query1.parambyname('incluir').AsString := QuotedList(st);
query1.parambyname('noincluir').AsString := QuotedList(st); // obviamente cambiando los datos.
query1.Open;


Como la rutina QuotedList recibe un TStrings, incluso puedes usar un memo, o combobox, o Listbox para que el usuario añada las modalidades.

Vuelvo a Editar el mensaje :D

Esto quizás sea más cómodo:

function QuotedListchklb( ctrl:TCheckListBox;const SoloChecked:Boolean = True):string;
var i:integer;
begin
result := '';
with ctrl do

for i:= 0 to Items.Count-1 do
if SoloChecked then
begin
if Checked[i] then
Result := Result +QuotedStr(Items[i])+',';
end
else
Result := Result +QuotedStr(Items[i])+',';

if Length(Result)>0 then
Delete(Result,Length(Result),1); //quito la ultima coma

end;


Saludos