powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / SQLite [игнор отключен] [закрыт для гостей] / запрос на выборку по новейшей дате
23 сообщений из 23, страница 1 из 1
запрос на выборку по новейшей дате
    #36536394
Dimkostav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте, товарищи!

Есть таблица karts_history. В ней колонки: kart_id(integer), karts_sost(integer), karts_date(date). У одного kart_id может быть несколько karts_sost и karts_date. Как выбрать kart_id, karts_sost, karts_date, чтобы при самой поздней karts_date karts_sost='2'?
Запрос
SELECT kart_id, karts_sost, MAX(karts_date) FROM karts_history WHERE karts_sost='2' GROUP BY kart_id
возвращает не то, что мне нужно.

Заранее спасибо:)
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #36537797
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Приведи скрипт создающий таблицу и заполняющий эту таблицу тестовыми данными.
Покажи желаемый результат.
Прочитай это: http://www.sql.ru/faq/faq_topic.aspx?fid=202
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #36538314
Dimkostav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White Owl, вот скрипт:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
CREATE TABLE test_values (id_karts_history integer NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,karts_sost integer,kart_id integer,karts_date date);

INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('100', '2', '2009-08-13');
INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('100', '1', '2009-08-23');
INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('100', '3', '2009-09-01');
INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('100', '2', '2009-10-05');

INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('101', '1', '2009-07-12');
INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('101', '2', '2009-08-01');
INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('101', '3', '2009-08-13');
INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('101', '1', '2009-09-01');

INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('102', '3', '2009-09-01');
INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('102', '2', '2009-09-08');
INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('102', '1', '2009-10-15');
INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('102', '3', '2009-11-12');

INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('103', '1', '2009-08-15');
INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('103', '3', '2009-08-25');
INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('103', '1', '2009-09-02');
INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('103', '2', '2009-09-07');

хочу получить:

Код: plaintext
1.
2.
3.
4.
5.
6.
id_karts_history    |	karts_id    | 	karts_sost   |	karts_date
---------------------------------------------------------------------
	 4          |	   100	    |        2       |   2009-10-05
---------------------------------------------------------------------
	16          |	   103	    |        2	     |   2009-09-07
---------------------------------------------------------------------
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #36538385
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А почему только эти две строки?
По какому принципу ты убрал из результата строки для kart_id 101 и 102?
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #36538607
Dimkostav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White OwlА почему только эти две строки?
По какому принципу ты убрал из результата строки для kart_id 101 и 102?

Потому что при самой поздней karts_date karts_sost='2' . Т.е. у kart_id='100' и kart_id='103' есть самая поздняя дата. У этих kart_id при этой самой поздней дате karts_sost='2' .
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #36538665
Dimkostav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DimkostavWhite OwlА почему только эти две строки?
По какому принципу ты убрал из результата строки для kart_id 101 и 102?

Потому что при самой поздней karts_date karts_sost='2' . Т.е. у kart_id='100' и kart_id='103' есть самая поздняя дата. У этих kart_id при этой самой поздней дате karts_sost='2' .
А у kart_id='101' и kart_id='102' при самой поздней karts_date karts_sost не равен '2'.
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #36540458
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
SELECT * 
FROM test_values t1
WHERE t1.karts_sost =  2  and
      t1.karts_date = (select max(karts_date)
                       from test_values t2
                       where t2.kart_id=t1.kart_id)
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #36540573
Dimkostav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White Owl, большое спасибо. Это мне очень помогло:)
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #36540585
MBG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MBG
Гость
White Owl
Код: plaintext
1.
2.
3.
4.
5.
SELECT * 
FROM test_values t1
WHERE t1.karts_sost =  2  and
      t1.karts_date = (select max(karts_date)
                       from test_values t2
                       where t2.kart_id=t1.kart_id)


Стараюсь в подобные темы не заглядывать, но у вас почему-то явная склонность делать лишние сканирования таблиц:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
sqlite> explain query plan SELECT * FROM test_values t1 WHERE t1.karts_sost =  2  
and t1.karts_date = (select max(karts_date) from test_values t2 where t2.kart_id=t1.kart_id);
 0 | 0 |TABLE test_values AS t1
 0 | 0 |TABLE test_values AS t2

sqlite> explain query plan select id_karts_history,kart_id,karts_sost,karts_date from test_values 
group by kart_id having karts_date=max(karts_date) and karts_sost='2';
 0 | 0 |TABLE test_values

Прошлый раз я об этом упоминал, приводя эксплайн результата, полученного с помощью моей функции distincton(), правда, забыл сказать, что такой же результат можно получить с помощью group by (хотя потребление памяти на действительно больших выборках, типа многогигабайтных журналов веб-серверов, может с group by оказаться существенно выше; впрочем, мой способ оптимизации предназначен для ручных разовых выборок и тестирования, а не для продакшен-приложений).
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #36540632
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MBGСтараюсь в подобные темы не заглядывать, но у вас почему-то явная склонность делать лишние сканирования таблиц:У меня склонность делать запросы максимально простые для чтения человеком. Оптимизацию я предпочитаю отдавать оптимизатору.
К тому-же, для ликвидации двойного сканирования в моем запросе достаточно сделать индекс на kart_id.

MBG
Код: plaintext
1.
2.
3.
sqlite> explain query plan select id_karts_history,kart_id,karts_sost,karts_date from test_values 
group by kart_id having karts_date=max(karts_date) and karts_sost='2';
 0 | 0 |TABLE test_values
А здесь, простите, нарушение стандарта. Если есть group by, то в списке возвращаемых полей можно указывать только поля по которым идет группировка и агрегаты.
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #36540642
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlMBGСтараюсь в подобные темы не заглядывать, но у вас почему-то явная склонность делать лишние сканирования таблиц:У меня склонность делать запросы максимально простые для чтения человеком. Оптимизацию я предпочитаю отдавать оптимизатору.
К тому-же, для ликвидации двойного сканирования в моем запросе достаточно сделать индекс на kart_id.Ой, соврал... Не достаточно. Все равно два сканирования.
Впрочем индексы все равно не помешают.
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #36540752
MBG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MBG
Гость
White OwlУ меня склонность делать запросы максимально простые для чтения человеком. Оптимизацию я предпочитаю отдавать оптимизатору.


Group by - совершенно другой тип обработки данных, и здесь явно тот случай, когда именно он нужен. Причем тут оптимизация?

White OwlА здесь, простите, нарушение стандарта. Если есть group by, то в списке возвращаемых полей можно указывать только поля по которым идет группировка и агрегаты.

Аналогичную выборку можно сделать и по стандарту, с помощью конструкции distinct on и соответствующей сортировки. Но, т.к. эта конструкция в эскулайт отсутствует, я назвал sqlite-specific решение, притом более гибкое. Что же касается стандарта как такового, то все СУБД имеют свои особенности реализации и я не думаю, что в форуме по СУБД SQLite стоит ломать копья из-за этого.

P.S. Ничего не имею против вас лично и не стоит обижаться на подсказку, сделанную во вполне корректной форме.
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #36540874
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MBGWhite OwlУ меня склонность делать запросы максимально простые для чтения человеком. Оптимизацию я предпочитаю отдавать оптимизатору.
Group by - совершенно другой тип обработки данных, и здесь явно тот случай, когда именно он нужен. Причем тут оптимизация?Оптимизация при том, что у меня нет "явной склонности делать лишние сканирования таблиц". Как я уже сказал, я пишу запрос в форме удобной для меня, а не для сервера. Если этот запрос тормозит, тогда я начинаю думать как его оптимизировать. Но обычно мне хватает оптимизатора встроенного в сервер. И до тех пор пока я пишу максимально простыми запросами я могу быть уверен что в следующей версии сервера мои "оптимизированные" запросы не встанут серверу поперек горла.
Плюс - смотри следующий коментарий...

MBG.... я назвал sqlite-specific решение, притом более гибкое. Что же касается стандарта как такового, то все СУБД имеют свои особенности реализации .Да, конечно. Просто тут уже играет роль то, что для меня SQLite стоит на четвертом-пятом месте. Я ее только в своих личных проектах использую. А на работе я сижу с зоопарком СУБД (практически все коммерческие базы в той или иной степени приходится обслуживать). Мне проще изворачиваться не выходя из стандарта. Особенности реализации я на зубок знаю только у SA и ASE, с остальными приходится в документацию лазить.

MBGP.S. Ничего не имею против вас лично и не стоит обижаться на подсказку, сделанную во вполне корректной форме.А я разве обижался?
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #36540912
MBG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MBG
Гость
White OwlОптимизация при том, что у меня нет "явной склонности делать лишние сканирования таблиц". Как я уже сказал, я пишу запрос в форме удобной для меня, а не для сервера. Если этот запрос тормозит, тогда я начинаю думать как его оптимизировать. Но обычно мне хватает оптимизатора встроенного в сервер. И до тех пор пока я пишу максимально простыми запросами я могу быть уверен что в следующей версии сервера мои "оптимизированные" запросы не встанут серверу поперек горла.

Имхо запрос с group by намного проще связанного подзапроса. И в данном случае как раз в тему, т.к. нужна дополнительная обработка групп в выборке, для чего group by и предназначен. Т.к. не помню ни одного вашего ответа с использованием group by, то и решил напомнить о такой возможности.

White Owl ... для меня SQLite стоит на четвертом-пятом месте. Я ее только в своих личных проектах использую. А на работе я сижу с зоопарком СУБД (практически все коммерческие базы в той или иной степени приходится обслуживать).

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

White OwlА я разве обижался?

Мне показалось, что предложенный мной вариант был воспринят как критика.
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #36540951
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MBGВпрочем, в рунете об этом говорить не имеет смысла, а вот в sqlite-users бывают интересные дискуссии на тему использования эскулайт в крупных проектах. А почему бы и не в рунете? Если для нас родным языком является русский, то трепаться проще на русском, а значит в рунете :) А из английских я просматриваю одним глазом только comp.db.sqlite.general.

А насчет крупных проектов... Сложно это переходить с проверенного годами комерческого продукта, на новый, пусть и в тысячу раз лучший, но все же новый продукт. Это ж потребует и новых людей или переобучение старых, и переписывание сотен клиентов... Мы вот с ASE 12.5 на ASE 15 переходим уже скоро год. А это всего-лишь новая версия старого продукта.
Переносить бизнес-процесс на базу другого типа? Смеетесь, да?
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #36540963
MBG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MBG
Гость
White OwlА почему бы и не в рунете? Если для нас родным языком является русский, то трепаться проще на русском, а значит в рунете :) А из английских я просматриваю одним глазом только comp.db.sqlite.general.

А насчет крупных проектов... ... Переносить бизнес-процесс на базу другого типа? Смеетесь, да?

Вот потому и не в рунете.
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #36541015
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MBGWhite OwlА насчет крупных проектов... ... Переносить бизнес-процесс на базу другого типа? Смеетесь, да?Вот потому и не в рунете.А в каком 'нете' запросто переходят с одной базы данных на другую? От страны это не зависит, только от размера компании.
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #36541075
MBG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MBG
Гость
White OwlА в каком 'нете' запросто переходят с одной базы данных на другую? От страны это не зависит, только от размера компании.

Это в основном зависит от того, что только в России компании могут себе позволить нелицензионное ПО, отсюда и появляется две-три версии оракла, микрософтэскуэль и проч. в пределах одной компании. Отсюда же отсутствие спроса на СУБД с открытым кодом, что легко проверить, посмотрев вакансии DBA и разработчиков.
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #36542931
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MBGЭто в основном зависит от того, что только в России компании могут себе позволить нелицензионное ПО, отсюда и появляется две-три версии оракла, микрософтэскуэль и проч. в пределах одной компании. Отсюда же отсутствие спроса на СУБД с открытым кодом, что легко проверить, посмотрев вакансии DBA и разработчиков.Ну вот уж неправда! Нелицензионное ПО здесь совершенно ни при чем.
Все зависит от размера компании и жесткости централизованного руководства. У нас например семнадцать официально независимых подразделений. Каждое из которых имеет свой собственный IT отдел. Со своими собственными system & data architectures. Отсюда и зоопарк СУБД... Причем все копии совершенно лицензионные :)
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #36543039
MBG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MBG
Гость
White OwlНу вот уж неправда! Нелицензионное ПО здесь совершенно ни при чем.
Все зависит от размера компании и жесткости централизованного руководства. У нас например семнадцать официально независимых подразделений. Каждое из которых имеет свой собственный IT отдел. Со своими собственными system & data architectures. Отсюда и зоопарк СУБД... Причем все копии совершенно лицензионные :)

Да, есть в России несколько компаний большого размера и с кучей подразделений - газпром, к примеру, или большая тройка сотовых операторов. Но зоопарк СУБД зачастую наблюдается и в гораздо меньших фирмах, где сотрудников примерно столько же, сколько у вас подразделений :-) Согласитесь, последним бывает затруднительно иметь даже единственную лицензионную копию oracle или mssql, особенно enterprize-версий (sic!) ;-)

Но мы отклонились от тему - в обсуждаемом запросе все же лучше сделать group by, а не менять эскулайт на оракл
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #37051686
Kolyvpro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2 White Owl:
А возможно ли уточнить этот запрос
White Owl
Код: plaintext
1.
2.
3.
4.
5.
SELECT * 
FROM test_values t1
WHERE t1.karts_sost =  2  and
      t1.karts_date = (select max(karts_date)
                       from test_values t2
                       where t2.kart_id=t1.kart_id)

так, чтобы он правильно обрабатывал значение NULL в [karts_date] для случая, когда первая запись для каждого [kart_id] не содержит даты?

Напр.: скрипт создания таблицы

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
CREATE TABLE test_values (id_karts_history integer NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,karts_sost integer,kart_id integer,karts_date date);

INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('100', '2', NULL);

INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('101', '1', NULL);
INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('101', '2', '2009-09-01');
INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('101', '2', '2009-08-01');
INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('101', '3', '2009-08-13');

INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('102', '2', NULL);

INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('103', '1', NULL);
INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('103', '3', '2009-08-25');

Кроме того, что хотел получить Dimkostav ([kart_id], для которых последнее (текущее) [kart_sost]=2),
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
id_karts_history    |	karts_id    | 	karts_sost   |	karts_date
---------------------------------------------------------------------
	1            |	   100	    |        2	     |   NULL
---------------------------------------------------------------------
	3            |	   101	    |        2	     |   2009-09-01
---------------------------------------------------------------------
	6            |	   102	    |        2	     |   NULL
---------------------------------------------------------------------

хотелось бы отдельно получить список значений последнего по дате (или единственного, первого - с [karts_date]=NULL) [kart_sost] для каждого [kart_id]:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
id_karts_history    |	karts_id    | 	karts_sost   |	karts_date
---------------------------------------------------------------------
	1            |	   100	    |        2	     |   NULL
---------------------------------------------------------------------
	3            |	   101	    |        2	     |   2009-09-01
---------------------------------------------------------------------
	6            |	   102	    |        2	     |   NULL
---------------------------------------------------------------------
	8            |	   103	    |        3	     |   2009-08-25
---------------------------------------------------------------------

Я так понимаю, что max(karts_date) не возвращает строки с NULL - требует в [karts_date] хотя бы пустой строки. Не то, чтобы было невозможно везде по таблице произвести такие замены (NULL -> '' или '1900-01-01'), но, можно ли обойтись без этого?

Спасибо,
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #37051743
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KolyvproКроме того, что хотел получить Dimkostav ([kart_id], для которых последнее (текущее) [kart_sost]=2),
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
id_karts_history    |	karts_id    | 	karts_sost   |	karts_date
---------------------------------------------------------------------
	1            |	   100	    |        2	     |   NULL
---------------------------------------------------------------------
	3            |	   101	    |        2	     |   2009-09-01
---------------------------------------------------------------------
	6            |	   102	    |        2	     |   NULL
---------------------------------------------------------------------
Да запросто:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
SELECT *
FROM test_values t1
WHERE t1.karts_sost =  2  and
      (t1.karts_date is null or
       t1.karts_date = (select max(karts_date)
                        from test_values t2
                        where t2.kart_id=t1.kart_id)
      );



[quot Kolyvpro]хотелось бы отдельно получить список значений последнего по дате (или единственного, первого - с [karts_date]=NULL) [kart_sost] для каждого [kart_id]:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
id_karts_history    |	karts_id    | 	karts_sost   |	karts_date
---------------------------------------------------------------------
	1            |	   100	    |        2	     |   NULL
---------------------------------------------------------------------
	3            |	   101	    |        2	     |   2009-09-01
---------------------------------------------------------------------
	6            |	   102	    |        2	     |   NULL
---------------------------------------------------------------------
	8            |	   103	    |        3	     |   2009-08-25
---------------------------------------------------------------------


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SELECT *
FROM test_values t1
WHERE t1.karts_date = (select max(karts_date)
                        from test_values t2
                        where t2.kart_id=t1.kart_id)
union
SELECT *
FROM test_values t1
WHERE not exists (select  1 
				  from test_values t2
                  where t2.kart_id=t1.kart_id and karts_date is not null)
ээээ... извращение какое-то. Но вроде работает.


KolyvproЯ так понимаю, что max(karts_date) не возвращает строки с NULL - требует в [karts_date] хотя бы пустой строки. Не то, чтобы было невозможно везде по таблице произвести такие замены (NULL -> '' или '1900-01-01'), но, можно ли обойтись без этого?"можно", не означает "нужно".
Что у вас там за таблица такая? С точки зрения физического мира эта самая karts_date может быть пустой? А она должна быть пустой?
...
Рейтинг: 0 / 0
запрос на выборку по новейшей дате
    #37060608
Kolyvpro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо.
Только, по-моему, этот запрос перестает работать, если к таблице добавить запись:
Код: plaintext
INSERT INTO test_values('kart_id', 'karts_sost', 'karts_date') VALUES ('101', '2', NULL);
Т.е. если начальное (при [karts_date]=NULL) значение [karts_sost]='2', то эта запись будет выдаваться наряду с позднейшей?

Второй запрос я так и не смог приспособить к своей таблице.
White OwlЧто у вас там за таблица такая? С точки зрения физического мира эта самая karts_date может быть пустой? А она должна быть пустой?

Таблица - с текстами правовых актов муниципального образования.
Текст каждого документа разбит на части (пронумерованы [BLOCK_ID]), каждая из которых может присутствовать в нескольких редакциях:
1. начальная (в поле VRS_DATE=NULL или VRS_DATE='')
2. измененная (в ней VRS_DATE устанавилвается по дате внесения изменений)
VRS_DATE (aka karts_date) при введении данных получало значение NULL или ''.
Установление значения происходило только в случае внесения в соответствующую часть документа изменений (добавлялась новая строка с тем же BLOCK_ID и VRS_DATE с датой вступления изменения в силу), при этом block_id брался от прежней версии.
Принадлежность части к документу устанавливается в поле [DOC_ID]
Порядок частей в документе устанавливается в [ORD]
Есть еще поле [BLOCK_UID] - типа autoinc(?)

Вот пример таблицы:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
CREATE TABLE [TPARTS] 
(
    [DOC_ID] ,
    [BLOCK_ID] ,
    [TEXT] ,
    [VRS_DATE] ,
    [BLOCK_UID] 
);

INSERT INTO [TPARTS] ([DOC_ID], [BLOCK_ID], [TEXT], [VRS_DATE], [BLOCK_UID]) VALUES ('100', '1', 'Заголовок документа 100', null,  101 );
INSERT INTO [TPARTS] ([DOC_ID], [BLOCK_ID], [TEXT], [VRS_DATE], [BLOCK_UID]) VALUES ('100', '2', 'Абзац 1', null,  102 );
INSERT INTO [TPARTS] ([DOC_ID], [BLOCK_ID], [TEXT], [VRS_DATE], [BLOCK_UID]) VALUES ('100', '3', 'Абзац 2 в начальной редакции', null,  103 );
INSERT INTO [TPARTS] ([DOC_ID], [BLOCK_ID], [TEXT], [VRS_DATE], [BLOCK_UID]) VALUES ('100', '3', 'Абзац 2 в редакции от 2010-11-23', '20101123',  106 );
INSERT INTO [TPARTS] ([DOC_ID], [BLOCK_ID], [TEXT], [VRS_DATE], [BLOCK_UID]) VALUES ('999', '1', 'Заголовок документа 999', null,  107 );
INSERT INTO [TPARTS] ([DOC_ID], [BLOCK_ID], [TEXT], [VRS_DATE], [BLOCK_UID]) VALUES ('999', '2', 'Абзац 1 документа 999 в редакции 2010-06-06', '20100606',  108 );
INSERT INTO [TPARTS] ([DOC_ID], [BLOCK_ID], [TEXT], [VRS_DATE], [BLOCK_UID]) VALUES ('100', '5', 'Подпись документа 100', null,  109 );
INSERT INTO [TPARTS] ([DOC_ID], [BLOCK_ID], [TEXT], [VRS_DATE], [BLOCK_UID]) VALUES ('100', '4', 'Абзац 3 документа 100', null,  110 );
INSERT INTO [TPARTS] ([DOC_ID], [BLOCK_ID], [TEXT], [VRS_DATE], [BLOCK_UID]) VALUES ('100', '3', 'Абзац 2 в редакции 2010-06-06', '20100606',  104 );
INSERT INTO [TPARTS] ([DOC_ID], [BLOCK_ID], [TEXT], [VRS_DATE], [BLOCK_UID]) VALUES ('100', '3', 'Абзац 2 в редакции 2010-02-02', '20100202',  105 );
INSERT INTO [TPARTS] ([DOC_ID], [BLOCK_ID], [TEXT], [VRS_DATE], [BLOCK_UID]) VALUES ('999', '3', 'Подпись документа 999', null,  122 );
INSERT INTO [TPARTS] ([DOC_ID], [BLOCK_ID], [TEXT], [VRS_DATE], [BLOCK_UID]) VALUES ('999', '2', 'Абзац 1 документа 999 в начальной редакции', null,  100 ); 

Проблема возникает при попытке получить все части одного документа (напр., с doc_id=100) на позднейшую (или любую другую дату):
не могу добиться, чтобы строки с (VRS_DATE ISNULL) or (VRS_DATE='') не выводились, если есть строка с тем же BLOCK_ID и с какой-нибудь датой.
запрос (по мотивам №1):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
SELECT *
FROM TPARTS t1
WHERE t1.DOC_ID = '100' and
      (t1.VRS_DATE is null or
       t1.VRS_DATE = (select max(VRS_DATE)
                        from TPARTS t2
                        where t2.BLOCK_ID=t1.BLOCK_ID)
      ) ORDER BY BLOCK_ID;
выдает дубликаты.

По запросу (по мотивам №2 )
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SELECT *
FROM TPARTS t1
WHERE DOC_ID='100' and
t1.VRS_DATE = (select max(VRS_DATE)
                        from TPARTS t2
                        where t2.BLOCK_ID=t1.BLOCK_ID
                        )
union
SELECT *
FROM TPARTS t1
WHERE DOC_ID='100' and 
      not exists (select  1 
                  from TPARTS t2
                  where t2.BLOCK_ID=t1.BLOCK_ID and VRS_DATE is not null)                 
ORDER BY BLOCK_ID;   
никак не могу получить, строку, где VRS_DATE=''.

Я думал, что это решаемо с помощью
Код: plaintext
UPDATE TPARTS SET VRS_DATE='20000101' WHERE (VRS_DATE IS NULL) or (VRS_DATE='');
НО!!?
После выполнения команды
Код: plaintext
1.
2.
3.
4.
5.
SELECT *
FROM TPARTS t1
WHERE DOC_ID='100' 
and t1.VRS_DATE = (select max(VRS_DATE)
                        from TPARTS t2
                        where t2.BLOCK_ID=t1.BLOCK_ID)
почему-то выдаются не все записи:
строка с [block_uid]= 102 не выдается?!

По-моему, я туплю. Надо перечитывать книжки?
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / SQLite [игнор отключен] [закрыт для гостей] / запрос на выборку по новейшей дате
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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