Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Опять массивы... / 9 сообщений из 9, страница 1 из 1
02.09.2008, 16:42
    #35518616
Большой Синий Кит
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять массивы...
Подскажите, пожалуйста, уважаемые профи!
Видимо, без массивов мне не обойтись...

Есть таблица, содержащая данные людей(упрощенно):

имя-|-фамилия-|-id_varchar varchar-|-id_integer int

Есть куча других таблиц, где содержится информация об этих людях, и в качестве идентификатора принадлежности этой информации кому-от из этих людей служит либо id_integer, либо id_varchar.

Нужно выбрать все неповторяющиеся записи, принадлежащие этим людям по определенным критериям поиска.
Я понимаю, что база сделана неверно, но это было до меня давным давно. А мне приходиться тащить этот груз за собой.

Пытался писать что-то такое:


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
CREATE OR REPLACE FUNCTION men_visited(fromdate "timestamp", todate "timestamp")
  RETURNS int4 AS
$BODY$
DECLARE
result int;
char_ids varchar[];
int_ids int[];
counter int;
current_id int;
BEGIN

select ARRAY(select distinct patient_id from rooms WHERE entered_in>=fromDate AND entered_in<=toDate 
  
   ) into int_ids;  //здесь летит ошибка, а как верно записать не знаю :(

  result=array_upper(int_ids, 1 );

select ARRAY(select distinct patient_id from note WHERE date>=fromDate AND date<=toDate) into char_ids;
  WHILE(counter<=array_upper(char_ids, 1 )
    LOOP
    SELECT id_patient WHERE id=char_ids[counter] into current_id;
    //и вот здесь нужно проверить, существует ли уже current_id в массиве int_ids, но как это       //сделать не могу найти. Просто в цикле проверять? - как-то некрасиво все получается...


return result;
END
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION men_visited(fromdate "timestamp", todate "timestamp") OWNER TO root;


Покажите где бы о подобном почитать или подправьте код, если не сложно, буду очень благодарен... в гугле рылся, но подобных задач не находил просто..
Заранее благодарен.
...
Рейтинг: 0 / 0
02.09.2008, 17:59
    #35518803
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять массивы...
опишите структуру таблиц и сформулируйте задачу в целом. возможно, ее удастся решить SQL-запросом.
...
Рейтинг: 0 / 0
03.09.2008, 09:28
    #35519442
Большой Синий Кит
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять массивы...
Спасибо за отклик!

К примеру, есть две таблицы:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
CREATE TABLE wardpatients
(
  id int4 NOT NULL DEFAULT nextval('wardpatients_id_seq'::regclass), -- primary key and unique identifier of the connection
  ward_id int4 NOT NULL, -- reference to the wards -> id (foreign key)
  patient_id int4 NOT NULL, -- reference to the patients -> id_patient (foreign key)
  admitted_on timestamp NOT NULL, -- date and time when the patient was admitted to the ward
  deposit numeric( 15 , 2 ) NOT NULL, -- deposit the patient pays in advance for being admitted
  deposit_pay_type char( 1 ), -- deposit type of payment
  extra_rate_per_day numeric( 15 , 2 ) NOT NULL, -- extra charges per day
  extra_tax1 numeric( 15 , 2 ) NOT NULL, -- tax 1 on extra charges per day
  extra_tax2 numeric( 15 , 2 ) NOT NULL -- tax 2 on extra charges per day
}


И


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
CREATE TABLE note
(
  note_string text,
  "index" int4 NOT NULL, -- Seriar number of the note (starts from 1).
  patient_id varchar( 40 ) NOT NULL, -- Foreign key reference to the patient table.
  date timestamp NOT NULL, -- Date and time this note image was inserted or last modified.
  id int4 NOT NULL DEFAULT nextval('note_id_seq'::regclass), -- Unique identifier of the note
  origin int2 NOT NULL DEFAULT  0 , -- Origin of this patient history record. This is a new value, so old records will have Patient History origin (0).
  doctor_id int4, -- Doctor who created this record. NULL means the doctor is unknown.
  lab_form_title varchar( 40 ),
  disease_code_id int4,
  surgery_code_id int4
}

В обеих таблицах есть столбец "patient_id". В одной из них он VARCHAR, во второй - int4.

В следующей таблице по этому id можно получить определенного пациента:

Код: plaintext
1.
2.
3.
4.
5.
6.
CREATE TABLE patient
(
  id varchar( 80 ) NOT NULL,  --варчаровский id
  ....
  id_patient int4 NOT NULL DEFAULT nextval('patient_id_patient_seq'::regclass), --int id
   ...

То есть и по варчаровскому id и по целочисленному id можно получить только одного пациента, и тот и другой уникальны.

Мне нужно провести выборку из обеих таблиц всех пациентов, но неповторяющихся.... Но я не могу делать это простым union запросов, потому что patient_id в первой таблице целочисленный, а во второй - варчаровский. Мне нужно после выборки во второй таблице, к примеру, получить соответствующие варчаровским id целочисленные id из таблицы patient....
Вот в чем проблема, и видимо, решить ее можно только с помощью массивов....
...
Рейтинг: 0 / 0
03.09.2008, 10:10
    #35519543
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять массивы...
Большой Синий КитНо я не могу делать это простым union запросовнаверное надо использовать join.

таким запросом можно выбрать уникальные записи из patients, для каждой из которых выполняются два условия: 1) существует связанная строка в таблице wardpatients удовлетворяющая ограничению по полю admitted_on, 2) существует строка в note с ограничением по date.

Код: plaintext
1.
2.
3.
4.
5.
select distinct patient.id, patient.id.patient
from patient
join wardpatients on ( wardpatients.patient.id = patient.id_patient )
join note on ( note.patient_id = patient.id )
where wardpatients.admitted_on between $fromDate and $toDate
and note.date between $fromDate and $toDate

Большой Синий КитВот в чем проблема, и видимо, решить ее можно только с помощью массивов....имхо, массивы в SQL не нужны.
...
Рейтинг: 0 / 0
03.09.2008, 10:44
    #35519635
Большой Синий Кит
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять массивы...
Большое Вам спасибо!!! :)

А как мне сделать подсчет количества этих записей?

Код: plaintext
1.
2.
3.
4.
5.
6.
SELECT count(SELECT distinct patient.id, patient.id_patient
from patient
join wardpatients on ( wardpatients.patient_id = patient.id_patient )
join note on ( note.patient_id = patient.id )
where wardpatients.admitted_on between fromdate and todate
and note.date between fromdate and todate);

говорит, что синтаксическая ошибка....
...
Рейтинг: 0 / 0
03.09.2008, 10:45
    #35519640
Большой Синий Кит
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять массивы...
Вопрос снимается :) туплю....
Еще раз большое Вам спасибо
...
Рейтинг: 0 / 0
03.09.2008, 10:51
    #35519662
Большой Синий Кит
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять массивы...
Эх... Вы немного не поняли вопроса... Я сам не объяснил точнее..
Дело еще в том, что если есть запись в первой таблице (wardpatients) это не значит, что обязана быть запись во второй таблице (note). То есть они не взаимосвязаны... А в ответе, который Вы дали, учитывается данная взаимосвязь.... как же быть??... :(
...
Рейтинг: 0 / 0
03.09.2008, 11:40
    #35519845
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять массивы...
Большой Синий Китесли есть запись в первой таблице (wardpatients) это не значит, что обязана быть запись во второй таблице (note).например через union

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
select patient.id, patient.id_patient
from patient
join wardpatients on ( wardpatients.patient.id = patient.id_patient )
where wardpatients.admitted_on between $fromDate and $toDate
union
select patient.id, patient.id_patient
from patient
join note on ( note.patient_id = patient.id )
where note.date between $fromDate and $toDate

или через outer join

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
select *
from (
  select distinct patient.id, patient.id_patient
  from patient
  join wardpatients on ( wardpatients.patient.id = patient.id_patient )
  where wardpatients.admitted_on between $fromDate and $toDate
) as p1
natural full outer join (
  select distinct patient.id, patient.id_patient
  from patient
  join note on ( note.patient_id = patient.id )
  where note.date between $fromDate and $toDate
) as p2
...
Рейтинг: 0 / 0
03.09.2008, 11:50
    #35519872
Большой Синий Кит
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять массивы...
Огромное Вам спасибо! :) помогло!
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Опять массивы... / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]