Author Topic: Не могу составить запрос  (Read 7302 times)

0 Members and 1 Guest are viewing this topic.

Offline blackmask

  • Newbie
  • *
  • Posts: 34
  • Karma: +0/-0
Не могу составить запрос
« on: August 02, 2008, 21:13:50 »
Есть таблица Peoples с полем bank. Т.е. у людей могут быть задолженности в разных банках. Допустим мне нужно узнать у каких людей задолженность сразу в двух банках(Урал и Сибирь).
написал запрос
select * from peoples
where bank = 'Урал' or bank = 'Сибирь'
Как и следовало ожидать он мне вернул людей у которых задолженность только в Урале, только в Сибири, а тех людей у которых и там и здесь вернул 2 раза.

написал:
select * from peoples
where bank = 'Урал' and bank = 'Сибирь'
здесь запрос уже ничего не возвращает. Я так понимаю, что он находит строки где банк = Урал и потом в них же ищет по второму условию и ничего не находит.

Как же мне написать, чтобы были только те люди, которые одновременно удовлетворяют обоим условиям??

Offline sie

  • Full Member
  • ***
  • Posts: 108
  • Karma: +0/-0
Не могу составить запрос
« Reply #1 on: August 02, 2008, 21:29:23 »
Если одному человеку может соответствовать несколько банков, не проще ли организовать два отношения - люди и банки - а между ними организовать связь один-ко-многим?
Почитайте теорию реляционных баз данных.

Offline visual

  • Hero Member
  • *****
  • Posts: 714
  • Karma: +0/-0
    • http://
Не могу составить запрос
« Reply #2 on: August 02, 2008, 22:49:01 »
Quote from: blackmask
Есть таблица Peoples с полем bank. Т.е. у людей могут быть задолженности в разных банках. Допустим мне нужно узнать у каких людей задолженность сразу в двух банках(Урал и Сибирь).
Code: [Select]
SELECT full_name, COUNT(full_name) AS bank_cnt
FROM people
GROUP BY full_name
HAVING (COUNT(full_name) > 1)
покажет у кого больше одной задолженности.
P.S. full_name - поле с Ф.И.О.
« Last Edit: August 02, 2008, 22:49:20 by visual »

Offline blackmask

  • Newbie
  • *
  • Posts: 34
  • Karma: +0/-0
Не могу составить запрос
« Reply #3 on: August 03, 2008, 20:45:07 »
Quote from: sie
Если одному человеку может соответствовать несколько банков, не проще ли организовать два отношения - люди и банки - а между ними организовать связь один-ко-многим?
Т.е. создать две таблицы? И напротив каждого человека писать ID банка и наоборот?
Поиск на самом деле будет не по двум параметрам, это я для простоты написал. Например, нужен человек у которого задолженность в банке Урал, задолженность более 50000, который проживает в Томске, и чтобы у этого человека была задолженность в банке Сибирь менее 40000
И так далее

Вот код на делфи с помощью которого можно искать человека у которого задолженность в банке более допустим 40000 и менее 60000

DataModule2.FindQuery.Active := false;
DataModule2.FindQuery.SQL.Clear;
DataModule2.FindQuery.SQL.Add('select * from peoples');
DataModule2.FindQuery.SQL.Add('where bank = '''+StringGrid1.Cells[0,1]+'''');   //Параметры для поиска вводятся в StringGrid
for i := 1 to AddFindForm.Row do begin                                                            //AddFindForm.Row - это количество заполненных полей для поиска
  if i <> 1 then
    DataModule2.FindQuery.SQL.Add('and bank = '''+StringGrid1.Cells[0,i]+'''');                                  //В нулевом поле выбирается банк
  DataModule2.FindQuery.SQL.Add('and minvalue '+StringGrid1.Cells[2,i]+' '+StringGrid1.Cells[3,i]);  // Во 2 поле условие(<,>,=) в 3 - сумма задолженности
end;

  DataModule2.FindQuery.Active := true;

И если вводишь поиск по одному банку, то все нормально, а если написать другой, то ничего не найдет.
Параметров для поиска на самом деле больше
« Last Edit: August 03, 2008, 21:17:32 by blackmask »

Offline sie

  • Full Member
  • ***
  • Posts: 108
  • Karma: +0/-0
Не могу составить запрос
« Reply #4 on: August 04, 2008, 00:07:48 »
Точнее не один-ко-многим, а многие-ко-многим. Например:

-- таблица людей
Code: [Select]
CREATE TABLE peoples (
 ID INTEGER,
 Full_name VARCHAR(30),
 City VARCHAR(30),
 ...,
 PRIMARY KEY (ID)
);
-- таблица банков
Code: [Select]
CREATE TABLE banks (
ID INTEGER,
Name VARCHAR(30),
...,
PRIMARY KEY (ID)
);
-- таблица долгов
Code: [Select]
CREATE TABLE dolgi (
PeopleID INTEGER,
BankID INTEGER,
Value DOUBLE PRECISION,
...,
PRIMARY KEY (PeopleID, BankID),
FOREIGN KEY (PeopleID) REFERENCES peoples (ID),
FOREIGN KEY (BankID) REFERENCES banks (ID)
);
Quote from: blackmask
Например, нужен человек у которого задолженность в банке Урал, задолженность более 50000, который проживает в Томске, и чтобы у этого человека была задолженность в банке Сибирь менее 40000
Code: [Select]
SELECT p.Full_name
FROM peoples p
WHERE (p.City = 'Томск') AND p.ID IN (
SELECT d.PeopleID
FROM dolgi d
LEFT JOIN banks b ON b.ID = d.BankID
WHERE (d.Value > 50000) AND (b.Name = 'Урал')
) AND p.ID IN (
SELECT d.PeopleID
FROM dolgi d
LEFT JOIN banks b ON b.ID = d.BankID
WHERE (d.Value < 40000) AND (b.Name = 'Сибирь')
)
и т.п.

Offline vak

  • Newbie
  • *
  • Posts: 19
  • Karma: +0/-0
Не могу составить запрос
« Reply #5 on: August 04, 2008, 09:14:22 »
Quote from: blackmask
...

Как же мне написать, чтобы были только те люди, которые одновременно удовлетворяют обоим условиям??
Вот текст необходимого запроса, и не надо заморачиваться со множеством таблиц.

select * from peoples where bank = 'Урал' and fio in (select fio from peoples where bank = 'Сибирь')

Offline blackmask

  • Newbie
  • *
  • Posts: 34
  • Karma: +0/-0
Не могу составить запрос
« Reply #6 on: August 04, 2008, 18:13:47 »
Всем огромное спасибо. Следуя совету vak у меня все получилось. Но другие советы тоже пригодятся.

Offline CRonaldo

  • Jr. Member
  • **
  • Posts: 50
  • Karma: +0/-0
Не могу составить запрос
« Reply #7 on: August 06, 2008, 15:15:45 »
А если кто-то опечатается?  
Всётаки думаю идея с несколькими таблицами правильна.
« Last Edit: August 06, 2008, 15:18:50 by CRonaldo »

Offline blackmask

  • Newbie
  • *
  • Posts: 34
  • Karma: +0/-0
Не могу составить запрос
« Reply #8 on: August 07, 2008, 16:06:12 »
У меня можно выбирать из выпадающего списка условия поиска. Сам ввести ничего не можешь

Offline CRonaldo

  • Jr. Member
  • **
  • Posts: 50
  • Karma: +0/-0
Не могу составить запрос
« Reply #9 on: August 15, 2008, 11:40:16 »
Так и места в базе меньше занимать будет. Да и вообще хоть правила нормализации будут соблюдаться я полагаю.

Offline blackmask

  • Newbie
  • *
  • Posts: 34
  • Karma: +0/-0
Не могу составить запрос
« Reply #10 on: September 08, 2008, 18:57:00 »
Да, спасибо. В конечном итоге я переделал, как мне посоветовал sie. Со временем понял, что так будет правильнее

Offline FireWall

  • Newbie
  • *
  • Posts: 29
  • Karma: +0/-0
Не могу составить запрос
« Reply #11 on: September 23, 2008, 08:28:16 »
Quote from: blackmask
Есть таблица Peoples с полем bank. Т.е. у людей могут быть задолженности в разных банках. Допустим мне нужно узнать у каких людей задолженность сразу в двух банках(Урал и Сибирь).
написал запрос
select * from peoples
where bank = 'Урал' or bank = 'Сибирь'
Как и следовало ожидать он мне вернул людей у которых задолженность только в Урале, только в Сибири, а тех людей у которых и там и здесь вернул 2 раза.

написал:
select * from peoples
where bank = 'Урал' and bank = 'Сибирь'
здесь запрос уже ничего не возвращает. Я так понимаю, что он находит строки где банк = Урал и потом в них же ищет по второму условию и ничего не находит.

Как же мне написать, чтобы были только те люди, которые одновременно удовлетворяют обоим условиям??

ммм, проверить нет возможности, но возможно:
select ID_user, FIO, Summa_Zadolzhnosti from peoples where bank = 'Урал'  and ID_user in (select ID_user from peoples where bank = 'Сибирь')
« Last Edit: September 23, 2008, 08:35:31 by FireWall »