1. Друзья, в это тяжёлое и непонятное для всех нас время мы просим вас воздержаться от любых упоминаний политики на форуме, - этим ситуации не поможешь, а только возникнут ненужные ссоры и обиды. Это касается также шуток и юмора на тему конфликта. Пусть войны будут только виртуальными, а политики решают разногласия дипломатическим путём. С уважением, администрация Old-Games.RU.

    Скрыть объявление
  2. Пожалуйста, внимательно прочитайте правила раздела.
  3. Если Вы видите это сообщение, значит, вы ещё не зарегистрировались на нашем форуме.

    Зарегистрируйтесь, если вы хотите принять участие в обсуждениях. Перед регистрацией примите к сведению:
    1. Не регистрируйтесь с никами типа asdfdadhgd, 354621 и тому подобными, не несущими смысловой нагрузки (ник должен быть читаемым!): такие пользователи будут сразу заблокированы!
    2. Не регистрируйте больше одной учётной записи. Если у вас возникли проблемы при регистрации, то вы можете воспользоваться формой обратной связи внизу страницы.
    3. Регистрируйтесь с реально существующими E-mail адресами, иначе вы не сможете завершить регистрацию.
    4. Обязательно ознакомьтесь с правилами поведения на нашем форуме, чтобы избежать дальнейших конфликтов и непонимания.
    С уважением, администрация форума Old-Games.RU
    Скрыть объявление

Soft Вопрос по Perl

Тема в разделе "Hard & Soft", создана пользователем Helmut, 24 мар 2010.

  1. AxXxB неадекват

    AxXxB

    Legacy

    Регистрация:
    13 ноя 2006
    Сообщения:
    1.663
    Helmut, то есть тебе нужно, чтобы в результате запроса получилась таблица, в которой в каждой записи было соответствие бланка и последней накладной? Если да, тогда вот:
    Код:
    SELECT blank.id, blank.number, temp.naklad FROM blank, temp WHERE temp.blank = blank.id AND temp.naklad = (SELECT MAX(naklad.id) FROM naklad)
    


    ---------- Сообщение добавлено в 14:59 ---------- Предыдущее сообщение размещено в 14:58 ----------

    Заработало?)

    ---------- Сообщение добавлено в 15:00 ---------- Предыдущее сообщение размещено в 14:59 ----------

    Не, мой запрос - лажа, ща переделаю
     
    Helmut нравится это.
  2. Helmut Herr Mannelig

    Helmut

    Переводчик

    Регистрация:
    18 мар 2008
    Сообщения:
    7.083
    AxXxB, Т.е. просто джоины заменить на условия where? Сейчас попробую.

    ЗЫ: Нет, это совсем не то. Грубо говоря имеется соотношение множество к множеству. По одной накладной (номер 1) на склад приходит несколько бланков (с номерами 1-10, например). По другой накладной (номер 2) бланки с номерами 1-3 переданы в другой офис. Т.е. в таблице blank содержится 10 записей, в таблице naklad - 2 записи, а в temp - 13 (10 связывающих с первй накладной и 3 со второй, причем id бланков, понятно, те же).
    На выходе должно получиться 10 записей (всего ведь 10 бланков), первые 3 из которых связаны с номером второй накладной (последней, где они фигурируют), остальные - с первой.

    Ага )
     
    Последнее редактирование: 13 янв 2012
  3. CSX

    CSX

    Регистрация:
    11 мар 2011
    Сообщения:
    186
  4. AxXxB неадекват

    AxXxB

    Legacy

    Регистрация:
    13 ноя 2006
    Сообщения:
    1.663
    Helmut, просто мне через WHERE удобнее, с точки зрения производительности JOIN оптимальнее, конечно. А так никакой разницы нету.
     
  5. Helmut Herr Mannelig

    Helmut

    Переводчик

    Регистрация:
    18 мар 2008
    Сообщения:
    7.083
    AxXxB, Но все равно, не то получается. Возможно потому, что SELECT MAX дается без дополнительных условий и по идее должен возвращать максимальный id накладной независимо от того, фигурировал в ней данный бланк или нет.

    Я дополнил предыдущий пост подробностями.
     
  6. John Freeman

    John Freeman

    Регистрация:
    13 май 2004
    Сообщения:
    14.241
    Я бы тут не изобретал говнопед, а тупо сделал по селекту для каждой таблицы по результатам, медленнее будет совсем несильно.
     
    Helmut нравится это.
  7. AxXxB неадекват

    AxXxB

    Legacy

    Регистрация:
    13 ноя 2006
    Сообщения:
    1.663
    Helmut, да, я уже понял, что не то, поэтому и написал, что запрос - лажа)
    По идее, должно работать вот так:
    Код:
    SELECT blank.id, blank.number, temp.naklad FROM blank LEFT JOIN temp ON blank.id = blank WHERE temp.naklad IN (SELECT MAX(temp.naklad) FROM temp GROUP BY temp.blank)
    
     
    Helmut нравится это.
  8. Helmut Herr Mannelig

    Helmut

    Переводчик

    Регистрация:
    18 мар 2008
    Сообщения:
    7.083
    John Freeman, Ты имеешь ввиду программный цикл, отправляющий отдельный запрос по результату каждой записи из первого запроса? Мне кажется, это как раз будет весьма ощутимо медленнее.

    Что-то типа
    PHP:
    $sth $dbh->prepare("SELECT id, number FROM blank");
    $sth->execute();
    while (
    $row $sth->fetchrow_arrayref())
    {
       
    $naklad $dbh->selectrow_array("SELCT MAX(naklad.id) FROM naklad INNER JOIN temp ON temp.naklad = naklad.id WHERE temp.blank = '$row->[0]'");
    }
    $sth->finish();
    Это получится совсем медленно.

    ---------- Сообщение добавлено в 15:49 ---------- Предыдущее сообщение размещено в 15:39 ----------

    AxXxB, Тоже не то. Теперь GROUP не работает. Выдает повторяющиеся записи с одинаковыми ID бланков. Если заменить group по blank.id - выдает только дублирующиеся записи.
     
    Последнее редактирование: 13 янв 2012
  9. AxXxB неадекват

    AxXxB

    Legacy

    Регистрация:
    13 ноя 2006
    Сообщения:
    1.663
    Helmut, хм, странно, я даже тестовые таблички сделал, вроде работает как надо.
    Вот такие

    ---------- Сообщение добавлено в 15:58 ---------- Предыдущее сообщение размещено в 15:56 ----------

    А, все, понял, где ступил - сделал несколько бланков в одной накладной, а не один бланк в нескольких накладных. Что-то сегодня голова не работает совсем :)

    ---------- Сообщение добавлено в 16:17 ---------- Предыдущее сообщение размещено в 15:58 ----------

    Во:
    Код:
    SELECT blank, blank.number, MAX(naklad) AS last_naklad FROM temp LEFT JOIN blank ON blank.id = blank GROUP BY blank
     
    Последнее редактирование: 13 янв 2012
    Helmut нравится это.
  10. Helmut Herr Mannelig

    Helmut

    Переводчик

    Регистрация:
    18 мар 2008
    Сообщения:
    7.083
    AxXxB, Во, кажется, теперь выдает то, что нужно. В смысле, дает верный id накладной. Теперь, как я понял, чтобы получить все данные по этой накладной, нужно добавлять вложенный запрос вида

    SELECT blank, blank.number, MAX(naklad) AS last_naklad, (SELECT number FROM naklad WHERE id = last_naklad) FROM temp LEFT JOIN blank ON blank.id = blank GROUP BY blank

    или JOIN naklad ON naklad.id = last_naklad

    Хотя нет, JOIN через псевдоним не сработает. В общем, это уже дело другое. Все равно надо еще прикручивать остальные подзапросы и условия выборки. Буду думать. Спасибо за совет.

    ЗЫ: Да, ни SELECT, ни JOIN по псевдониму ведь не провести. Можно только подзапросы вида (SELECT number FROM naklad WHERE id = MAX(temp.naklad)), (SELECT date FROM naklad WHERE id = MAX(temp.naklad)), причем по одному для каждого поля таблицы naklad. Или я что-то не так понял?
     
    Последнее редактирование: 13 янв 2012
  11. AxXxB неадекват

    AxXxB

    Legacy

    Регистрация:
    13 ноя 2006
    Сообщения:
    1.663
    Helmut, да, это уже задачка нетривиальная, мне кажется. После плясок с бубном получилось вот что:

    SELECT blank.id AS b_id, blank.number AS b_num, naklad.id AS n_id, naklad.number AS n_num FROM temp LEFT JOIN blank ON blank.id = temp.blank LEFT JOIN naklad ON naklad.id = temp.naklad HAVING naklad.id = (SELECT MAX(naklad) FROM temp WHERE blank = b_id)

    Работает раза в три помедленнее, чем предыдущий запрос.
     
    Helmut нравится это.
  12. John Freeman

    John Freeman

    Регистрация:
    13 май 2004
    Сообщения:
    14.241
    Helmut, а такой inner join будет не ощутимо медленнее? Вы нарушаете простые правила...
     
    Helmut нравится это.
  13. Helmut Herr Mannelig

    Helmut

    Переводчик

    Регистрация:
    18 мар 2008
    Сообщения:
    7.083
    AxXxB, Спасибо. Выглядит достаточно гибко для прикрутки дополнительных подзапросов и условий выборки. Такой вариант я предполагал, но не придумал как SELECT MAX без дополнительных условий может работать по ограниченной области. Мысля в этом направлении застряла.

    John Freeman,
    Теоретически один запрос с джоинами должен все-таки быстрее обрабатываться, чем пара сотен последовательных. Хотя бы из-за хедеров запросов и отработки интерпретатором перла. Пожалуй, сделаю скрипт, заполняющий тестовую таблицу парой тысяч значений и проверю на время оба варианта.
     
    Последнее редактирование: 15 янв 2012
    AxXxB нравится это.
  14. Helmut Herr Mannelig

    Helmut

    Переводчик

    Регистрация:
    18 мар 2008
    Сообщения:
    7.083
    Забавно. Не, читать специализированные форумы, конечно, нужно, можно много нового и полезного узнать. Но сходу применять прочитанное как аксиому...

    Искал тут ответ на один вопрос, в списке тем на форуме попался заголовок - как прописью распарсивать число? Вспомнил, что когда-то тоже занимался этим вопросом, почитал. Потом поискал аналогичные темы на других форумах. Везде, в том числе на хабре, предлагаются какие-то предельно громоздкие и замороченные решения. Млин, я бы мог понять, что люди, дающие советы на форуме, выдают то, что им не лень писать. Но ведь то же самое можно сделать парой десятков строчек вместо нескольких страниц или подключаемых модулей на те же несколько страниц.

    Пару лет назад я написал простенькую подпрограммку для прописи сумм в актах. Причем делал в спешке и навскидку. Наверняка можно еще проще сделать, если подумать. Но работает. Свою сверхсекретную днявочку захламлять не буду, оставлю тут, благо не оффтоп. Может потом когда-нибудь еще пригодится.

    PHP:
    sub propis {
        
    my ($int,$s,@a) = (sprintf("%.2f",$_[0]),($_[1])?$_[1]:' ',());
        
    my ($smr,$smk) = ($int 1e9) ? split(/\./,$int) : (0x 2;
        
    my @split(//, sprintf("%09d",$smr));
        
    my @split(//, sprintf("%02d",$smk));
        
    my @qw (ноль одна две тысяча тысячи тысяч миллион миллиона миллионов);
        @
    a[1..20,30,40,50,60,70,80,90,100,200,300,400,500,600,700,800,900] = qw (
            
    один два три четыре пять шесть семь восемь девять десять одиннадцать двенадцать тринадцать четырнадцать пятнадцать шестнадцать семнадцать восемнадцать девятнадцать
            двадцать тридцать сорок пятьдесят шестьдесят семьдесят восемьдесят девяносто сто двести триста четыреста пятьсот шестьсот семьсот восемьсот девятьсот
        
    );
        
    my $rub = ($smr 0) ? ($r[0] > 0) ? $a[$r[0]*100].$s '' $t[0];
        
    my $kop = ($smk 0) ? ($k[0] > 1) ? ($k[1] > 0) ? $a[$k[0]*10].$s $a[$k[0]*10] : '' $t[0];
        
    $kop .= ($k[0] == 1) ? $a[$k[0]*10+$k[1]] : ($k[1] < 3) ? $t[$k[1]] : $a[$k[1]] if ($k[0] == || $k[1] > 0);
        
    $rub .= ($r[1] == 1) ? $a[$r[1]*10+$r[2]].$s $a[$r[1]*10].$s if ($r[1] > 0) ;
        
    $rub .= ($r[2] == 1) ? $a[$r[2]].$s.$t[6] : $a[$r[2]].$s if ($r[2] > && $r[1] != 1);
        
    $rub .= ($r[2] > && $r[2] < && $r[1] != 1) ? $t[7] : $t[8] if ($smr >= 1e6 && ($r[1] == || $r[2] != 1));
        
    $rub .= $s if ($smr >= 1e6 && $r[3]+$r[4]+$r[5] > 0);
        
    $rub .= $a[$r[3]*100].$s if ($r[3] > 0);
        
    $rub .= ($r[4] == 1) ? $a[$r[4]*10+$r[5]].$s $a[$r[4]*10].$s if ($r[4] > 0);
        
    $rub .= ($r[5] == 1) ? $t[1].$s.$t[3] : ($r[5] == 2) ? $t[2].$s $a[$r[5]].$s if ($r[5] > && $r[4] != 1);
        
    $rub .= ($r[5] > && $r[5] < && $r[4] != 1) ? $t[4] : $t[5] if ($r[3]+$r[4]+$r[5] > && ($r[4] == || $r[5] != 1));
        
    $rub .= $s if ($smr >= 1e3 && $r[6]+$r[7]+$r[8] > 0);
        
    $rub .= ($r[7]+$r[8] > 0) ? $a[$r[6]*100].$s $a[$r[6]*100] if ($r[6] > 0);
        
    $rub .= ($r[7] == 1) ? $a[$r[7]*10+$r[8]] : $a[$r[7]*10] if ($r[7] > 0);
        
    $rub .= ($r[7] > 1) ? $s.$a[$r[8]] : $a[$r[8]] if ($r[8] > && $r[7] != 1);
        return(
    $rub$kop);
    }
     
    Последнее редактирование: 15 апр 2014
    Val07og и Bato-San нравится это.
  15. Helmut Herr Mannelig

    Helmut

    Переводчик

    Регистрация:
    18 мар 2008
    Сообщения:
    7.083
    Продолжаем развлекаться. Всем хорош Аякс, но неудобен же, зараза. Основная работа - на стороне клиента, приходится писать кучу функций для обработки каждого конкретного случая, если нужно взаимодействовать одновременно с несколькими объектами - слать кучу запросов или гонять туда-сюда целый блок HTML.
    Возникла идея переложить всю работу на сторону сервера. Получается намного гибче и удобнее. В общем, на яваскрипте только одна функция - универсальный обработчик ответа сервера. На сервер шлется запрос, оттуда приходит ответ, который кроме обычного кода содержит метки, описывающие желаемое взаимодействие с нужными объектами HTML, ответ обрабатывается и исполняется весь разом. На стороне сервера выглядит как-то так:
    PHP:
    <SPLIT target="testDiv" property="innerHTML">
    тут тексткоторый помещается в блочный объект с id="testDiv".
    <
    SPLIT target="testText" property="value">
    а этот текст пойдет в текстовое поле testText.
    <
    SPLIT target="testCheck" property="checked">
    true #поставим галку в чекбокс
    <SPLIT target="testDiv" property="innerHTML">
    добавим текста в testDivсклеив с предыдущим.
    <
    SPLIT target="testDiv" property="className">
    testcss #изменим класс дива
    <SPLIT target="testDiv" property="style">
    dispaly:block #и добавим ему стиля
    <script>
    а этот включенный в текст JS-скрипт вырежется из ответа и после тогокак все действия с объектами будут произведеныотправится на исполнение
    </script>
    В общем, получается как-то поживее, особенно при работе со страницами, содержащими множество зависящих друг от друга динамичных объектов, чем описывать все это на жабаскрипте. Недостаток - в обработчике ответа приходится добавлять обработчики исключений, т.к. некоторые свойства в JS меняются не напрямую. Например, style или innerHTML для тега <SELECT>.

    Отсюда вопрос в студию: я совершенно уверен, что изобретаю велосипед и подобные инструменты есть. Но мне как-то не попадались. Кто-нибудь видел что-то похожее?

    ЗЫ: Впрочем, самому сделать один черт интереснее, да и удобнее под конкретно свои задачи. Но посмотреть на чужие наработки все равно не вредно.
     
  1. На этом сайте используются файлы cookie, чтобы персонализировать содержимое, хранить Ваши предпочтения и держать Вас авторизованным в системе, если Вы зарегистрировались.
    Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie.
    Скрыть объявление