LINUX.ORG.RU

Правильный запрос

 ,


1

2

Уважаемые форумчане! Требуется ваша помощь!

(SQLite3, PHP7)

Имеем три таблицы:

  • таблица ld - список людей
  • таблица pr - список предметов
  • таблица sv - связи между людьми и предметами.

К примеру взял человек предмет - тогда INSERT id человека и id предмета в таблицу связей.

CREATE TABLE ld (id INTEGER PRIMARY KEY AUTOINCREMENT, ch TEXT NOT NULL UNIQUE);

CREATE TABLE pr (id INTEGER PRIMARY KEY AUTOINCREMENT, pr TEXT NOT NULL UNIQUE);

CREATE TABLE sv (id INTEGER PRIMARY KEY AUTOINCREMENT, id_ch INTEGER NOT NULL, id_pr INTEGER NOT NULL, UNIQUE(ch, pr));

Мне необходимо получить:

  • Сколько человек связано с каждым предметом
  • (также) Сколько предметов связано с каждым человеком
  • Вывести список предметов, которые не связаны с людьми (которых нет в таблице связей)
  • (также) Вывести список людей, которые не связаны с предметами (которых нет в таблице связей)

Подскажите, как правильно сделать запросы?



Последнее исправление: tonchikp (всего исправлений: 1)

считает пустые rowid, которые были удалены, а мне нужно только те что с записями

это что-то новенькое. дай посмотреть, что делаешь и как получаешь, сравниваешь с эталоном

bvn13 ★★★★★
()
Ответ на: комментарий от bvn13

например:

  • делаем insert в таблицу, предположим rowid получился 1
  • потом делаем delete из таблицы
  • потом снова делаем insert в таблицу, rowid уже 2
  • делаю select count(*) показывает 2
tonchikp
() автор топика
Ответ на: комментарий от tonchikp

делаем insert в таблицу, предположим rowid получился 1
потом делаем delete из таблицы
потом снова делаем insert в таблицу, rowid уже 2

логично, автоинкремент так работает

делаю select count(*) показывает 2

а вот в это не верю. пруф дай.

bvn13 ★★★★★
()
Ответ на: комментарий от bvn13

С удовольствием бы, но как? Возможно я ошибаюсь, что он считает пустые rowid - это моё предположение, но точно количество вручную посчитанных записей и количество которое выдаёт SELECT COUNT(*) не сходится.

tonchikp
() автор топика

Домашняя работа? SELECT COUNT(*) FROM TABLE_NAME считает правильное количество строк в таблице. Ищи ошибку в другом месте.

anonymous
()
Ответ на: комментарий от anonymous

Не домашняя работа, скорее работа на дому :) Не считает правильно почему-то. Подскажите, почему так может происходить, число которое он выдаёт больше на 5 бывает. Считал вручную, смотрел вывод по sqlitebrowser, не сходится с числом select count(*) и всё тут.

tonchikp
() автор топика
Ответ на: комментарий от vertexua

Не уверен что правильно Вас понял, но select * выдаёт все записи, то есть ожидаемое (правильное) количество

tonchikp
() автор топика
Ответ на: комментарий от bvn13

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

Но суть вопроса была «как правильно», если select count(*) - правильный путь, значит буду и дальше так делать. Просто я подумал что раз он выдаёт неверный результат - значит как-то по другому нужно.

tonchikp
() автор топика
Ответ на: комментарий от bvn13

Хм, странно, у Вас верный результат выдаёт. Может я делал без UNIQUE ограничения, вечером залезу в код и скажу точнее.

tonchikp
() автор топика
Ответ на: комментарий от tonchikp

Сравнив два запроса, select * и select count(*) можно понять что если количество результатов не совпадает, то дело в очень странном поведении SqLite и значить нужно копаться в их 1) документации 2) настройках 3) багах. Там может быть вполне написана ересь вроде «у нас count обновляется с задержкой».

Если количество результатов сопадает, но не правильно, то значит delete не работает, в выборку для удаления не попадает нужная строка.

vertexua ★★★★★
()
Ответ на: комментарий от vertexua

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

vertexua ★★★★★
()
Ответ на: комментарий от bvn13

Можно попробовать сделать удаление в отдельной транзакции, не закоммитить, в отдельной транзакции выполнить count

vertexua ★★★★★
()

Количество предметов пытался вывести так, но выдаёт неверное значение (считает пустые rowid, которые были удалены, а мне нужно только те что с записями):

SELECT COUNT(*) FROM pr;

Решено, пришлось ещё раз всю базу вручную просмотреть и код, нашёл свою ошибку, не было при создании написано ограничение unique, поэтому в базу прокрались null и что ещё хуже дубликаты, которые потом не выводятся, и поэтому количество меньшее получается

tonchikp
() автор топика
Ответ на: комментарий от vertexua

Транзакции я тоже не использовал, а зря.

tonchikp
() автор топика
Ответ на: комментарий от tonchikp

Решено

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

bvn13 ★★★★★
()
Ответ на: комментарий от tonchikp

За пол года забудеш что имел ввиду под pr

ZuBB ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.