|
Помогите с запросом...
|
|||
---|---|---|---|
#18+
Есть табличка: userid datein dateoutA0 11 F4 D0 17.02.2019 11:55 17.02.2019 12:46A0 11 F4 D0 17.02.2019 13:55 17.02.2019 19:26A0 11 F4 D0 11.02.2019 15:11 11.02.2019 16:46A0 11 F4 D0 08.02.2019 17:11 08.02.2019 18:111B AD F0 D1 18.02.2019 10:28 18.02.2019 15:291B AD F0 D1 19.02.2019 11:19 19.02.2019 15:19A0 11 F4 D0 19.02.2019 11:20 19.02.2019 17:29 Мне надо получить минимальное значение по datein и максимальное по dateout в разрезе одного userid за месяц. Запрос за одно число составил: Код: sql 1. 2. 3. 4.
Как мне сделать запрос на весь месяц? Скажем февраль (с 1-гог по 28-ое), что бы табличка имела вид (шапка): :userid datein 01 dateout 01datein 02 dateout 02datein 03 dateout 03 …… datein 28 dateout 28 ... |
|||
:
Нравится:
Не нравится:
|
|||
19.02.2019, 13:02 |
|
Помогите с запросом...
|
|||
---|---|---|---|
#18+
Это называется PIVOT и выглядит в MySQL весьма печально. лучше получи то же в столбик, а сводную делай на клиенте. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.02.2019, 15:15 |
|
Помогите с запросом...
|
|||
---|---|---|---|
#18+
Мне не совсем надо развернуть. Мне надо это получить в строку. Обрисую немного по-другому: Дана табличка: Таблица 1. Журнал регистраций CREATE TABLE skud.registration ( id int(11) NOT NULL AUTO_INCREMENT, userid varchar(20) DEFAULT NULL, datein timestamp NULL DEFAULT CURRENT_TIMESTAMP, dateout timestamp NULL DEFAULT '0000-00-00 00:00:00', wplaceid varchar(30) DEFAULT NULL, PRIMARY KEY (id), UNIQUE INDEX id (id) ) ENGINE = INNODB AUTO_INCREMENT = 10 AVG_ROW_LENGTH = 3276 CHARACTER SET cp1251 COLLATE cp1251_general_ci; SET NAMES 'utf8'; INSERT INTO skud.registration(id, userid, datein, dateout, wplaceid) VALUES (1, 'A0 11 F4 D0', '2019-02-18 11:55:19', '2019-02-18 12:46:03', '1'); INSERT INTO skud.registration(id, userid, datein, dateout, wplaceid) VALUES (2, 'A0 11 F4 D0', '2019-02-18 13:55:26', '2019-02-18 14:46:37', '1'); INSERT INTO skud.registration(id, userid, datein, dateout, wplaceid) VALUES (3, 'A0 11 F4 D0', '2019-02-18 15:11:25', '2019-02-18 16:46:46', '1'); INSERT INTO skud.registration(id, userid, datein, dateout, wplaceid) VALUES (4, 'A0 11 F4 D0', '2019-02-18 17:11:25', '2019-02-18 18:11:19', '1'); INSERT INTO skud.registration(id, userid, datein, dateout, wplaceid) VALUES (5, '1B AD F0 D1', '2019-02-18 10:28:02', '2019-02-18 15:29:06', '2'); INSERT INTO skud.registration(id, userid, datein, dateout, wplaceid) VALUES (6, '1B AD F0 D1', '2019-02-19 11:19:59', '0000-00-00 00:00:00', '1'); INSERT INTO skud.registration(id, userid, datein, dateout, wplaceid) VALUES (7, 'A0 11 F4 D0', '2019-02-19 11:20:08', '0000-00-00 00:00:00', '1'); INSERT INTO skud.registration(id, userid, datein, dateout, wplaceid) VALUES (8, '1B AD F0 D1', '2019-02-19 07:56:01', '2019-02-19 15:56:31', '1'); INSERT INTO skud.registration(id, userid, datein, dateout, wplaceid) VALUES (9, '1B AD F0 D1', '2019-02-19 09:57:21', '2019-02-19 17:50:35', '2'); В ней фиксируются дата, время, id rfid метки (userid) с карточки юзера, когда пришел(datein) и ушел(dateout) на объект (wplaceid). Таблица 2. Пользователи CREATE TABLE skud.users ( id int(11) NOT NULL AUTO_INCREMENT, username varchar(20) DEFAULT NULL, userid varchar(20) DEFAULT NULL COMMENT 'rfid метка', ufio varchar(100) DEFAULT NULL, pid int(5) DEFAULT NULL, user_group varchar(30) DEFAULT NULL, PRIMARY KEY (id), UNIQUE INDEX id (id) ) ENGINE = INNODB AUTO_INCREMENT = 3 AVG_ROW_LENGTH = 8192 CHARACTER SET cp1251 COLLATE cp1251_general_ci; INSERT INTO skud.users(id, username, userid, ufio, pid, user_group) VALUES (1, 'iii', 'A0 11 F4 D0', 'Иванов И.И.', 2, 'признак группы'); INSERT INTO skud.users(id, username, userid, ufio, pid, user_group) VALUES (2, 'paa', '1B AD F0 D1', 'Петров А.А', 2, 'признак группы'); Таблички связываются по userid. Задача состоит в том чтобы вывести в грид месячную сетку и отобразить в ней дату прихода(минимальное значение из datein за определенный день ) и дату ухода (максимальное значение из dateout за определенный день). Сделал запрос: Код: sql 1. 2. 3. 4. 5. 6. 7.
Результат: ufio sdate din doutПетров А.А 19.2019 07:56 17:50Иванов И.И. 19.2019 11:20 00:00 Поле sdate вывел для сверки, оно не нужно. Так вот задача состоит в том чтобы вы вести данные за месяц и заполнить вот такую таблицу(грид в приложении). Колонки создаются динамически исходя из количества дней месяца, думал присваивать поля колонкам а ля din1,dout1,din2,dout2...din28,dout28. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.02.2019, 16:44 |
|
Помогите с запросом...
|
|||
---|---|---|---|
#18+
Валерий666заполнить вот такую таблицуДобавьте группировку по дате (и сортировку по необходимости) - получите в выборке по одной строке данных для каждого юзера за каждую дату. Затем в цикле на клиенте перегоняете данные в шаблон таблицы или в массив или ещё куда. Валерий666думал присваивать поля колонкам а ля din1,dout1,din2,dout2...din28,dout28. И тридцать (плюс/минус) раз приджойнить таблицу `registration` для получения каждой пары полей? Можно, конечно, и динамически сформировать текст запроса сообразно количеству дней месяца, если ну очень хочется. Что там будет с тормозами - лучше не думать. Не знаю, чем/как таблица заполняется в данном конкретном случае. Если используется что-то вроде html-кода или строки текста как набора значений через разделитель (CSV), тогда, в принципе, можно попробовать в сторону GROUP_CONCAT посмотреть. Однако, открытым остается вопрос пропуска дат (Сидоров в какие-то дни вообще не приходил на работу и/или не уходил). ... |
|||
:
Нравится:
Не нравится:
|
|||
19.02.2019, 18:28 |
|
Помогите с запросом...
|
|||
---|---|---|---|
#18+
vkleВалерий666заполнить вот такую таблицуДобавьте группировку по дате (и сортировку по необходимости) - получите в выборке по одной строке данных для каждого юзера за каждую дату. Затем в цикле на клиенте перегоняете данные в шаблон таблицы или в массив или ещё куда. Валерий666думал присваивать поля колонкам а ля din1,dout1,din2,dout2...din28,dout28. И тридцать (плюс/минус) раз приджойнить таблицу `registration` для получения каждой пары полей? Можно, конечно, и динамически сформировать текст запроса сообразно количеству дней месяца, если ну очень хочется. Что там будет с тормозами - лучше не думать. Не знаю, чем/как таблица заполняется в данном конкретном случае. Если используется что-то вроде html-кода или строки текста как набора значений через разделитель (CSV), тогда, в принципе, можно попробовать в сторону GROUP_CONCAT посмотреть. Однако, открытым остается вопрос пропуска дат (Сидоров в какие-то дни вообще не приходил на работу и/или не уходил). Думал обойтись минимальными программными расчетами. Быстродействие - пока не попробуешь, не будет известно:-) Видимо придется отказаться от дбгрида и рисовать в простом гриде, раз уж обрабатывать на стороне клиента. Но тогда встает вопрос, если понадобится вывести весь штат в этот самый грид, а это получится матрица ~ 1300х30(31). На сколько быстро отрисутюся 40 000 ячеек... ... |
|||
:
Нравится:
Не нравится:
|
|||
19.02.2019, 21:59 |
|
Помогите с запросом...
|
|||
---|---|---|---|
#18+
Валерий666Но тогда встает вопрос, если понадобится вывести весь штат в этот самый грид, а это получится матрица ~ 1300х30(31).Встречный вопрос. В штате вашей конторы есть какой-то вундеркинд, который способен за один присест осмыслить и осознать содержимое всех этих овер сорок тыщ ячеек? ;-) Вот если таковой вдруг найдется, то тыкнет куда надо и скачает или отправит на печать заранее подготовленный отчет в PDF. Готовить можно ночью и неспешно. Задача разовая в любом случае (раз в месяц). Есть предложение исходить из реальных задач. В реальности оперативные задачи масштаба предприятия гораздо проще, скорее всего, чем сорок тыщ ячеек просматривать. Что-то вроде выдать списки опозданцев по подразделениям (с какой-то статистикой и отметками о причинах) или списки неуспеванцев, задержавшихся на работе более одного часу. А то и вовсе не подробные списки, а лишь статистику по рабочему времени. Для масштаба подразделения, вполне возможно, потребуется какая-то более мелкая и подробная детализация, но там и сотрудников будет в разы меньше. Валерий666На сколько быстро отрисутюся 40 000 ячеек...Если уж говорить о производительности, так у нее множество аспектов. Может, на выборке с группировкой и агрегированием будут бОльшие тормоза, нежели на отрисовке. Кто-нибудь проверял на реальных данных? Исходные данные в таблице, как мне кажется, не вполне оптимальны для желаемой выборки. Для чего, к примеру, в таблице зафиксирован каждый вход и каждый выход? Ведь, гипотетически, можно же было фиксировать только первый вход за дату (INSERT IGNORE с составным индексом сотрудник+дата) и сохранять только последний выход (INSERT ... ON DUPLICATE KEY UPDATE с тем же индексом). Агрегатные функции и группировка уже не нужны, строк в исходной таблице существенно меньше (в основном, за счет бегающих на обед или покурить). Однако, вполне догадываюсь, что без подробной статистки в случае чего и не укажешь куряке, что из восьми часов на рабочем месте он был лишь три. Можно ли держать в базе две таблицы, а то и три, с разной степенью детализации? А статистику собирать по мере поступления данных, а не вычислять всю скопом раз в месяц? Наверно, несколько десятков мегабайт в год на диске не слишком большая плата за дополнительные таблицы и простоту запросов. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.02.2019, 23:09 |
|
Помогите с запросом...
|
|||
---|---|---|---|
#18+
Вобщем получилось такое чудовище, которое формируется на стороне клиента: Нужно ли это оптимизировать или это нормально? Код: sql 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. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60.
... |
|||
:
Нравится:
Не нравится:
|
|||
20.02.2019, 11:54 |
|
Помогите с запросом...
|
|||
---|---|---|---|
#18+
56 коррелированных подзапросов - это даже в страшном сне не приснится... это не оптимизировать надо, а стереть как страшный сон и начать заново. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.02.2019, 12:47 |
|
Помогите с запросом...
|
|||
---|---|---|---|
#18+
запрос Код: sql 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. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60.
fiddle PS. Конечно, вместо registration.dateout LIKE '2019-02-28%' надо использовать DATE(registration.dateout) = '2019-02-28' , но мне уже надоело... ... |
|||
:
Нравится:
Не нравится:
|
|||
20.02.2019, 13:21 |
|
|
start [/forum/topic.php?fid=47&fpage=39&tid=1829293]: |
0ms |
get settings: |
9ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
35ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
48ms |
get tp. blocked users: |
2ms |
others: | 14ms |
total: | 146ms |
0 / 0 |