Найти отличительные идентификаторы, когда дата выполнения всегда находится в последний день каждого месяца

Вы повторно используете один и тот же объект Statement для выполнения двух запросов. Когда stmt используется для выполнения второго запроса, объект ResultSet, возвращенный предыдущим оператором, закрывается. Создайте два объекта для каждого запроса.

Пример:

Statement stmt = conn.createStatement();
Statement stmt1 = conn.createStatement();
...
ResultSet res = stmt.executeQuery(Query);

...

while(res.next()){

     S_Code = res.getString("S_Code");
     Query1 = "SELECT * From Subjects WHERE Prerequisite = '"+S_Code+"'";
     res1 = stmt1.executeQuery(Query1); // use a separate statement

    while(res1.next()){

        DLM.addElement(res.getString("S_Code"));
    }

}

Это объясняется в следующей цитате из Statement API docs :

По умолчанию только один объект ResultSet на объект Statement может быть открыт одновременно. Поэтому, если чтение одного объекта ResultSet чередуется с чтением другого, каждый из них должен быть сгенерирован разными объектами Statement. Все методы выполнения в интерфейсе Statement неявно закрывают текущий ResultSet объект статута, если существует открытый.

blockquote>

Также настоятельно рекомендуется закрыть ресурсы JDBC в файле обратный порядок их размещения, т. е. вы должны закрыть Statement, затем закройте Connection, и вы должны сделать это в блоке finally:

catch(SQLException e){
    JOptionPane.showMessageDialog(null, e.toString());
} finally {
    if(res != null) {
        res.close();
    }
    if(res1 != null) {
        res1.close();
    }
    if(stmt != null) {
        stmt.close();
    }
    if(stmt1 != null) {
        stmt1.close();
    }
    if(conn != null) {
         conn.close();
    }
}

re, используя Java 7, вы можете использовать оператор try-with-resources для автоматического закрытия этих ресурсов (без явного вызова метода close()):

// try-with-resources statement declaring two resources
try(Connection conn  = DriverManager.getConnection(url,username,password);
    Statement stmt = conn.createStatement()) {
    ...
} catch(SQLException e){
    JOptionPane.showMessageDialog(null, e.toString());
}

Попробуемые ресурсы будут не забудьте закрыть объект Statement, затем Connection после их использования.

0
задан a_horse_with_no_name 13 July 2018 в 19:48
поделиться

4 ответа

Вы можете сделать:

select id
from t
group by id
having sum(case when extract(day from due_dt + interval '1 day') = 1 then 1 else 0 end) = count(*);

Это использует стандартные функции ANSI / ISO для арифметики дат. Они, как правило, зависят от базы данных, но идея одинакова во всех базах данных - добавьте один день и посмотрите, равен ли день месяца для всех строк.

0
ответ дан Gordon Linoff 17 August 2018 в 12:12
поделиться
  • 1
    Большое спасибо, Гордон! Он работает именно так, как я этого хочу. Я немного изменил его: выберите ID из группы t по ID, имеющему сумму (случай, когда день (листинг (DUE_DT как дата) + 1) = 1, затем 1 else 0 end) = count (*) – Yelena 13 July 2018 в 20:00

Идея довольно проста:

  • вы находитесь в последний день месяца, если (месяц назначенного срока) не совпадает (месяц с даты + 1 день ). Это охватывает все случаи в течение года, високосного года и так далее.
  • оттуда, если (количество строк для одного id) совпадает с (количество строк для этого id, которое является последним днем ​​месяца), у вас есть победитель.

Я попытался написать пример (не тестировался). Вы не указываете, какая БД, поэтому я предполагаю, что cte (общее табличное выражение) доступно. Если не просто поставить cte в подзапрос. Точно так же я не уверен, что dateadd и interval работают одинаково во всех диалектах.

with addlastdayofmonth as (
select
    id
    -- adding a 'virtualcolumn', 1 if last day of month 0 otherwise
  , if(month(dateadd(due_date, interval '1' day)) != month(due_date), 1 ,0) as onlastday
from
  table
)
select 
    id
  , count(*) - sum(onlastday) as alwayslastday 
from
  addlastdayofmonth
group by
  id
having
  -- if count(rows) == count(rows with last day) we have a winner
  halwayslastday = 0
0
ответ дан Guillaume 17 August 2018 в 12:12
поделиться
  • 1
    Спасибо, Гийом. Я пытаюсь проверить, работает ли ваш код. – Yelena 13 July 2018 в 20:02

Если вы используете SQL Server 2012+, вы можете использовать функцию EOMONTH () для достижения этой цели:

SELECT DISTINCT ID FROM [table]
WHERE DUE_DT = EOMONTH(DUE_DT)

http://rextester.com/VSPQR78701

0
ответ дан Ian-Fogelman 17 August 2018 в 12:12
поделиться
  • 1
    Спасибо, Ян, но если у меня есть несколько записей на каждый идентификатор, когда срок соответствует совпадению с концом месяца, ваш код отобразит этот идентификатор в конечном списке. Я хочу убедиться, что во все времена (все строки) совпадают на протяжении всей истории. – Yelena 13 July 2018 в 19:55

MySQL-Version (кредиты @Gordon Linoff)

SELECT
    ID
FROM
    <table>
GROUP BY
    ID
HAVING
    SUM(IF(day(DUE_DT + interval 1 Day) = 1, 1, 0)) = COUNT(ID);

Исходный ответ:

SELECT MAX(DUE_DT) FROM <table> WHERE ID = <the desired ID>

или если вы хотите все MAX ( DUE_DT) для каждого уникального идентификатора

SELECT ID, MAX(DATE) FROM <table> GROUP BY ID

0
ответ дан Pilan 17 August 2018 в 12:12
поделиться
  • 1
    Привет, Пилан, спасибо за ваше предложение. Но я хочу создать SQL-запрос, который дает мне список отдельных идентификаторов, срок погашения которых всегда находится в последний день каждого месяца. Ваш запрос дает мне что-то еще. – Yelena 13 July 2018 в 19:21
  • 2
    last day of each month фактический последний день или только самый высокий день из данных? – Pilan 13 July 2018 в 19:29
  • 3
    фактический последний день. Например, для ID = 2 последний день месяца будет = '1/31/2014', но запись будет '1/30/2014'. Поэтому мы не можем выбрать этот идентификатор. – Yelena 13 July 2018 в 19:31
  • 4
    Значит, вам нужны только идентификаторы с фактическим прошлым днем? Или почему мы не можем выбрать этот идентификатор? Скажите мне, какой желаемый результат для ID: 2 | Дата: 1/30/2014 и т. Д. – Pilan 13 July 2018 в 19:49
  • 5
    Привет, Пилан. Желаемый результат: ID = 1. Мы не выбираем DUE_DT. Мы пытаемся составить список отдельных идентификаторов. В нашем случае единственным ID является ID = 1, потому что его срок всегда находится в последний день каждого месяца. – Yelena 13 July 2018 в 20:42
Другие вопросы по тегам:

Похожие вопросы: