За последние 24 часа нас посетили 18014 программистов и 1700 роботов. Сейчас ищут 1520 программистов ...

Вложенные SQL-запросы

Тема в разделе "PHP для новичков", создана пользователем Garett09, 23 дек 2024 в 15:19.

Метки:
  1. Garett09

    Garett09 Новичок

    С нами с:
    Понедельник
    Сообщения:
    3
    Симпатии:
    0
    Добрый день всем! :) У меня тут такая вот задачка - есть приложение Win32, написанное на C++ (Visual Studio), в ней идет обращение к PostgreSQL-базе; возникла необходимость основные запросы перевести в Веб-формат, чтобы можно было посмотреть выборки к базе из браузера. Накопал php, слепил пока пару скриптов, перенес SQL-запросы - можно пользоваться. Но вот есть более сложные запросы, вложенные - вот фрагмент на C++:
    CRecordset recset_monitors( &database );
    SqlString = "SELECT employers.employer_code, main.name,main.s_n,main.inventory_code, main.model,main.device_type_code FROM employers INNER JOIN (main INNER JOIN history ON main.device_code = history.device_code) ON employers.employer_code = history.employer_code";
    SqlString+=" WHERE (history.employer_code)=52 AND (main.device_type_code)=2";

    recset_monitors.Open(CRecordset::forwardOnly,SqlString,CRecordset::readOnly);

    //Входим в цикл, пробегая по каждой записи
    while( !recset_monitors.IsEOF() )
    {
    //проходим по всем записям с кодом сотрудника=52
    recset_monitors.GetFieldValue("name",sDeviceName);
    recset_monitors.GetFieldValue("model",sDeviceModel);
    recset_monitors.GetFieldValue("inventory_code",sDeviceInvCode);
    recset_monitors.GetFieldValue("s_n",sDeviceSerial);
    //так как у нас образовалось несколько значений с кодом сотрудника=52 (Склад), то нужно проверять перед каждой
    //последующей записью, уникален ли серийный номер устройства. Потому что иначе, если устройство побывало у разных
    //сотрудников, включая нахождение на Складе, все эти записи останутся в таблице History и попадут в результирующую
    //выборку.
    if(temp_Serial==sDeviceSerial) //если запись совпала с уже просмотренной (то есть мы уже видели это устройство),
    { recset_monitors.MoveNext(); } //сразу переходим к следующей и тоже проверим ее в начале цикла
    else { //если же устройство еще не встречалось, обрабатываем:

    /////////////////внутри запроса создаем еще один запрос, чтобы выяснить, кто владеет устройством на текущий момент (берем то значение, где дата более поздняя)

    CRecordset recset4( &database );
    CString sEmpl,sEmplPrev;

    SqlString2 = "SELECT main.s_n, employers.employer, history.date FROM main INNER JOIN (employers INNER JOIN history ON employers.employer_code = history.employer_code) ON main.device_code = history.device_code";
    SqlString2+=" WHERE s_n=";
    SqlString2+="'";
    SqlString2+=sDeviceSerial; //передаем в запрос серийный номер текущего устройства
    SqlString2+="' ORDER BY history.date"; //упорядочиваем по дате сверху вниз

    recset4.Open(CRecordset::forwardOnly,SqlString2,CRecordset::readOnly);
    while( !recset4.IsEOF() )

    {
    sEmplPrev=sEmpl;
    recset4.GetFieldValue("date",sDate); //извлекаем дату


    sYear=sDate;
    sMonth=sDate;
    sDay=sDate;
    sYear.Delete(4,6);
    sMonth.Delete(7,3);
    sMonth.Delete(0,5);
    sDay.Delete(0,8);
    sDate=sDay+"."+sMonth+"."+sYear; //приводим ее к правильному формату DD.MM.YYYY

    recset4.GetFieldValue("employer",sEmpl);
    recset4.MoveNext();

    }

    recset4.Close();//закрываем текущий набор данных
    if (sEmpl=="Склад") //проверяем, числится ли в итоге рассматриваемое устройство на Складе (то есть дата у такой записи должна быть
    //самое поздней, после нее устройство не должно быть где-то еще
    {
    //добавляем запись в список
    m_ListMonitorsStore.AddItem(_T(sDeviceName),_T(sDeviceModel),_T(sDeviceInvCode),_T(sDeviceSerial),_T(sEmplPrev),_T(sDate));
    Если в двух словах - нужно выяснять, у кого и когда побывало искомое устройство и затем упорядочить выборку по дате (во вложенном запросе), чтобы вытащить последнего на текущий момент его владельца. Такое можно реализовать на php? Спасибо.
     
  2. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.857
    Симпатии:
    748
    Адрес:
    Татарстан
    все можно .. но в вашей лапше просто так никто не будет разбираться
     
  3. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    439
    Симпатии:
    84
    Адрес:
    Бавария, Германия
    Добрый день!

    Конечно можно. НО в данном случае, речь идёт о запросах на языке "SQL".
    Если простые запросы на PHP Вы освоили, то видимо разобралисись с классами и функцями.
    и остаются мелочи, типа $ перед именем переменной и в строковых операторах вместо "+" , "."
    Если у Вам нужна помощь с SQL-запросами, то покажите, пожалуйста, структуру данных.

    p.s. Не по сути. Пожалуйста, используйте в редакторе опцию "Код", как - см. в приложение.

    Удачи!
     

    Вложения:

    • code.pdf
      Размер файла:
      192,6 КБ
      Просмотров:
      2
  4. Garett09

    Garett09 Новичок

    С нами с:
    Понедельник
    Сообщения:
    3
    Симпатии:
    0
    Вы знаете, вот именно с php только-только пытаюсь разобраться. Мне бы хотя бы в первом приближении разобраться с передачей значений переменных в запрос, ну например:
    $result = pg_query($conn,"SELECT device_type,device_type_code from public.device_type WHERE device_type_code=1");
    Здесь для примера просто руками вписал фильтр в запрос, но мне нужно создать переменную, скажем, $filter, задать ей значение '1' и передать ее в этот запрос - как правильно будет выглядеть синтаксис? Спасибо за помощь.
     
  5. Garett09

    Garett09 Новичок

    С нами с:
    Понедельник
    Сообщения:
    3
    Симпатии:
    0
    Более-менее разобрался, во всяком случае, вложенный запрос работает. В любом случае - спасибо :)
     
  6. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    439
    Симпатии:
    84
    Адрес:
    Бавария, Германия
    Добрый день!
    Функции PostgreSQL:
    Код (Text):
    1. <?php
    2. $query = "SELECT device_type, device_type_code from public.device_type WHERE device_type_code = $1";
    3. $result = pg_prepare($conn, "my_query", $query);
    4. //значение переменной 1
    5. $filter =1;
    6. $result = pg_execute($conn, "my_query", [$filter]);
    7. //значение переменной 5
    8. $filter = 5;
    9. $result = pg_execute($conn, "my_query", [$filter]);
    Класс PDO
    PHP:
    1. <?php
    2. $pdo = new PDO('....');
    3. $query = "SELECT device_type, device_type_code from public.device_type WHERE device_type_code = :device_type_code";
    4. $sth = $pdo->prepare($query);
    5. $filter = 1;
    6. $sth->execute( [':device_type_code' => $filter ]);
    Улачи!
     
    #6 Vladimir Kheifets, 25 дек 2024 в 10:55
    Последнее редактирование: 25 дек 2024 в 11:09