Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Вернуть записи из второй таблицы, не попадающие под условие первой
 
 автор: admiral   (26.02.2010 в 01:39)   письмо автору
 
 

SELECT 
    lab_analyses.*, COUNT(*) 
FROM lab_analyses
  RIGHT OUTER JOIN s_contingent_cod ON lab_analyses.contingent_code = s_contingent_cod.code_id
WHERE
  lab_analyses.lpu_id = 1
GROUP BY
  lab_analyses.contingent_code
ORDER BY
  s_contingent_cod.code_id


В общем мне нужно сделать так, чтобы из таблицы s_contingent_cod выводились все записи, даже те, которые не подходили по условию. Тоесть чтобы они были заполнены значением NULL.
Пробовал менять на лефт джойн - безрезультатно.

  Ответить  
 
 автор: Trianon   (26.02.2010 в 01:51)   письмо автору
 
   для: admiral   (26.02.2010 в 01:39)
 

>В общем мне нужно сделать так, чтобы из таблицы s_contingent_cod выводились все записи,
даже те, которые не подходили по условию. Тоесть чтобы они были заполнены значением NULL.

Вы вообще-то не просите делать вывод хоть каких-нибудь полей из таблицы s_contingent_cod

>Пробовал менять на лефт джойн - безрезультатно.

Для простоты восприятия и вправду стоило бы развернуть соединение в LEFT JOIN .
Сейчас читается тяжело (хотя на результат и не влияет)..

Кроме того, дла описанного SELECT у Вас странным образом выбран ORDER BY . Как мне кажется.

  Ответить  
 
 автор: admiral   (26.02.2010 в 02:26)   письмо автору
 
   для: Trianon   (26.02.2010 в 01:51)
 

SELECT
  lab_analyses.*, COUNT(*) AS counts
FROM
  lab_analyses
LEFT OUTER JOIN 
  s_contingent_cod ON lab_analyses.contingent_code = s_contingent_cod.code_id
WHERE
  lab_analyses.lpu_id = 1
GROUP BY
  lab_analyses.contingent_code
ORDER BY
  s_contingent_cod.code_id


Подправил запрос немного. Я хочу чтобы из таблицы s_contingent_cod выводились все записи, а в lab_analyses возвращалии NULL.
Такое возможно?

  Ответить  
 
 автор: Trianon   (26.02.2010 в 08:52)   письмо автору
 
   для: admiral   (26.02.2010 в 02:26)
 

Возможно всё (или как минимум очень многое из того) что удастся сформулировать.

1.
>Я хочу чтобы из таблицы s_contingent_cod выводились все записи, а в lab_analyses возвращалии NULL.

У Вас не перечислена в разделе SELECT ни одна колонка таблицы s_contingent_cod - следовательно Вы не планируете выводить полей этой таблицы в принципе.

2. Не выводя ни одной колонки из s_contingent_cod , Вы почему-то ставите колонку этой таблицы полем задания порядка вывода.
Получается чушь вида "Выведи данные о президентах стран, упорядочив по ИНН супруга директора центробанка".

  Ответить  
 
 автор: admiral   (26.02.2010 в 12:58)   письмо автору
 
   для: Trianon   (26.02.2010 в 08:52)
 

SELECT 
  s_contingent_cod.*, lab_analyses.*,  COUNT(*) AS counts 
FROM 
  lab_analyses 
LEFT OUTER JOIN  
  s_contingent_cod ON lab_analyses.contingent_code = s_contingent_cod.code_id 
WHERE 
  lab_analyses.lpu_id = 1 
GROUP BY 
  s_contingent_cod.code_id
ORDER BY 
  s_contingent_cod.code_id


Сделал даже группировку по s_contingent_cod.code_id
Все равно результат выводит 8 записей соответствующие условие lab_analyses.lpu_id = 1
Но в таблице s_contingent_cod всего 22 записи - это справочник, и вот мне все нужно чтобы даже если не соответствовало условие lab_analyses.lpu_id = 1 в колонках таблицы lab_analyses заполнялись значениями NULL, а колонки таблицы s_contingent_cod, выводили все записи.

  Ответить  
 
 автор: Trianon   (26.02.2010 в 13:20)   письмо автору
 
   для: admiral   (26.02.2010 в 12:58)
 

Как только Вы начинаете мешать поля и агрегатные функции без разбора - запрос становится семантически неоднозначным.

Вы бы привели дамп таблиц (структуры и данных) и показали, какой результат ожидаете и почему именно такой, а не другой.

  Ответить  
 
 автор: admiral   (26.02.2010 в 14:16)   письмо автору
55.2 Кб
 
   для: Trianon   (26.02.2010 в 13:20)
 

Trianon , для удобства дамп и структуру прикрепил в аттаче.
Теперь по порядку.

Запрос:
SELECT 
  s_contingent_cod.code_id, lab_analyses.number_research, COUNT(*) AS counts 
FROM 
  lab_analyses 
LEFT OUTER JOIN  
  s_contingent_cod ON lab_analyses.contingent_code = s_contingent_cod.code_id 
WHERE 
  lab_analyses.lpu_id = 1 
GROUP BY 
  s_contingent_cod.code_id
ORDER BY 
  s_contingent_cod.code_id 


При таком запросе, результат таков:

+---------+-----------------+--------+
| code_id | number_research | counts |
+---------+-----------------+--------+
|     102 |            7351 |      2 |
|     103 |            7390 |      1 |
|     106 |            7390 |     21 |
|     108 |            7357 |      1 |
|     114 |            7351 |    172 |
|     115 |            7383 |     17 |
|     116 |            7384 |     17 |
|     121 |            7385 |     17 |
+---------+-----------------+--------+
8 rows in set (0.00 sec)



А я хочу получить такой результат:

+---------+-----------------+--------+
| code_id | number_research | counts |
+---------+-----------------+--------+
|     102 |            7351 |      2 |
|     103 |            7390 |      1 |
|     104 |            NULL |   NULL |
|     105 |            NULL |   NULL |
|     106 |            7390 |     21 |
|     108 |            7357 |      1 |
|     109 |            NULL |   NULL |
|     111 |            NULL |   NULL |
|     112 |            NULL |   NULL |
|     113 |            NULL |   NULL |
|     114 |            7351 |    172 |
|     115 |            7383 |     17 |
|     116 |            7384 |     17 |
|     118 |            NULL |   NULL |
|     120 |            NULL |   NULL |
|     121 |            7385 |     17 |
|     122 |            NULL |   NULL |
|     123 |            NULL |   NULL |
|     124 |            NULL |   NULL |
|     125 |            NULL|    NULL |
|     128 |            NULL |   NULL |
|     200 |            NULL |   NULL |
+---------+-----------------+--------+


Я отчет генерирую в xls - формат, поэтому в шаблоне ексель файла справочники заполнятются автоматизировано из базы, поэтому
при выводе результата отчета мне нужно именно в такой вариации. Можно, конечно, эти справочники в скрипте прописать, но это не совсем правильно с точки зрения программирования, да справочники могут дополняться.

  Ответить  
 
 автор: Trianon   (26.02.2010 в 19:53)   письмо автору
 
   для: admiral   (26.02.2010 в 14:16)
 

Проверяйте, пожалуйста, данные, перед постингом.
Дамп Вас испорчен.
Поле number_research (первичный ключ таблицы lab_analyses) содержит повторяющиеся значения.
Это как минимум - то на чем встал импорт.

[sub]Кроме того, дампы естественнее снимать расширенными вставками ( так, чтоб один INSERT-запрос на таблицу)
Хотя это не столь существено - разглядывать такой дамп проще, и места он занял бы впятеро меньше.
[/sub]

  Ответить  
 
 автор: admiral   (26.02.2010 в 21:05)   письмо автору
 
   для: Trianon   (26.02.2010 в 19:53)
 

Я ошибся только в том, что структуру БД показал Вам из старого архива. То есть у меня используется составной индекс, поэтому дубликатов как бы нет в таком случае -
CREATE TABLE IF NOT EXISTS `spid_lab_analyses` (
  `number_research` int(5) NOT NULL auto_increment,
  `patient_id` int(6) NOT NULL,
  `id_type_research` int(5) NOT NULL,
  `data` date NOT NULL,
  `lpu_id` int(4) NOT NULL,
  `clinical_payment` set('0','1') NOT NULL,
  `contingent_code` int(11) NOT NULL COMMENT 'контингент код',
  PRIMARY KEY  (`number_research`,`id_type_research`,`data`,`clinical_payment`),
  KEY `contingent_code` (`contingent_code`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 AUTO_INCREMENT=7393 ;

  Ответить  
 
 автор: admiral   (26.02.2010 в 21:10)   письмо автору
 
   для: Trianon   (26.02.2010 в 19:53)
 

Видимо, дело было в составном индексе.

  Ответить  
 
 автор: admiral   (26.02.2010 в 21:56)   письмо автору
 
   для: admiral   (26.02.2010 в 21:10)
 

Trianon, спасибо, я разобрался

  Ответить  
 
 автор: Trianon   (26.02.2010 в 23:51)   письмо автору
 
   для: admiral   (26.02.2010 в 21:56)
 

Тогда где запрос?

  Ответить  
 
 автор: admiral   (27.02.2010 в 03:14)   письмо автору
 
   для: Trianon   (26.02.2010 в 23:51)
 

не хрена не работает.
Даже индексы по удалял и все записи очистил и создал 3-4 тестовых. И тот же запрос не работает. Тоесть там где надо NULL не возвращает. НО!!! Когда я убираю условие WHERE, то все работает. Но понятное дело меня это не устраивает. Потому что мне нужно за конкртеный lpu_id вывести отчеты за каждый контингент код. А контингент коды, которых нет в таблице lab_analyses за указанный lpu_id нужно чтобы MySQL заполнила пустыми значениями.
Trianon, дружище, помоги что ли.

  Ответить  
 
 автор: Trianon   (27.02.2010 в 08:32)   письмо автору
 
   для: admiral   (27.02.2010 в 03:14)
 

Ну что "помоги-то"?
Дампа-то нет?

  Ответить  
 
 автор: admiral   (27.02.2010 в 13:57)   письмо автору
1.5 Кб
 
   для: Trianon   (27.02.2010 в 08:32)
 

Дам и структуру обоих таблиц прикрепил в аттаче. Я пока удалил индексы. Запрос сам вот (я даже пока не стал смешивать выборку с агрегатными функциями):
SELECT
 lab_analyses.number_research, s_contingent_cod.code_id
FROM
  spid_lab_analyses
LEFT JOIN 
  s_contingent_cod ON lab_analyses.contingent_code = s_contingent_cod.code_id
WHERE 
  lab_analyses.lpu_id = 1
GROUP BY 
  s_contingent_cod.code_id
ORDER by 
  s_contingent_cod.code_id


В результате запроса данного у меня выводит всего одну запись, хотя я добиваюсь того, чтобы их было ровно 22, поскольку в spid_s_contingent_cod их 22. Значит в остальных записях строка number_research, таблицы lab_analyses должна быть заполнено неопределенным значением NULL, а строка code_id таблицы s_contingent_cod в порядке сортировки.

p.s Для удобства дам сделал как Вы говорили

  Ответить  
 
 автор: Trianon   (27.02.2010 в 16:20)   письмо автору
 
   для: admiral   (27.02.2010 в 13:57)
 

SELECT
    s_contingent_cod.code_id
    lab_analyses.number_research, 
  FROM
    s_contingent_cod
  LEFT JOIN 
    spid_lab_analyses
     ON 
               lab_analyses.contingent_code = s_contingent_cod.code_id
           AND lab_analyses.lpu_id = 1
  GROUP BY 
    s_contingent_cod.code_id
  ORDER by 
    s_contingent_cod.code_id

  Ответить  
 
 автор: admiral   (27.02.2010 в 16:38)   письмо автору
 
   для: Trianon   (27.02.2010 в 16:20)
 

MySQL - сила! Trianon, благодарю Вас за помощь, теперь понимаю что мой запрос логически был неправильный)) Вы, кстати, в конструкции SELECT запятую не в том месте поставили))

  Ответить  
 
 автор: Trianon   (27.02.2010 в 17:27)   письмо автору
 
   для: admiral   (27.02.2010 в 16:38)
 

строки менял. по смыслу.
За Вас, между прочим.

  Ответить  
 
 автор: admiral   (27.02.2010 в 17:45)   письмо автору
 
   для: Trianon   (27.02.2010 в 17:27)
 

>строки менял. по смыслу.
>За Вас, между прочим.

Не совсем понял что значит меняли?

  Ответить  
 
 автор: Trianon   (27.02.2010 в 17:48)   письмо автору
 
   для: admiral   (27.02.2010 в 17:45)
 

сперва было так:
SELECT
    lab_analyses.number_research, 
    s_contingent_cod.code_id

  Ответить  
 
 автор: admiral   (27.02.2010 в 17:58)   письмо автору
 
   для: Trianon   (27.02.2010 в 17:48)
 

Ну да, а Вы написали так

SELECT 
    lab_analyses.number_research
    s_contingent_cod.code_id,

И запрос вернул ошибку)))

  Ответить  
 
 автор: Trianon   (27.02.2010 в 18:04)   письмо автору
 
   для: admiral   (27.02.2010 в 17:58)
 

ага.
Я в следующий раз всё же сделаю над собой усилие.
И вообще ничего не напишу.

  Ответить  
 
 автор: admiral   (27.02.2010 в 18:27)   письмо автору
 
   для: Trianon   (27.02.2010 в 18:04)
 

)))
Любите Вы стебаться)))
Ну да вам простительно)

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования