#sql #ms-access
#sql #ms-access
Вопрос:
Мне нужно показать студенческие удостоверения, которые сдавали тест как между 01/09/2007 — 31/12/2007, так и между 01/01/2008 — 20/06/2008. По какой-то причине это не работает. могу ли я получить от вас некоторую помощь? спасибо (текст ниже — это то, что я написал).
SELECT studentId
FROM gradesTbl
WHERE testDate BETWEEN "01/09/2007" AND "31/12/2007" AND
WHERE testDate BETWEEN "01/01/2008" AND "20/06/2008";
Комментарии:
1. Удалите второе
WHERE
ключевое слово.2. «между концом 2007 года» И «между началом 2008 года» … 😁
3. Поскольку эти два критерия фактически выполняются последовательно, вы можете просто использовать
BETWEEN #01/09/2007# AND #20/06/2008#
.
Ответ №1:
Вы можете сделать это с помощью EXISTS
:
SELECT DISTINCT g1.studentId
FROM gradesTbl AS g1
WHERE
EXISTS (SELECT 1 FROM gradesTbl AS g2 WHERE g2.studentId = g1.studentId AND g2.testDate BETWEEN "01/09/2007" AND "31/12/2007")
AND
EXISTS (SELECT 1 FROM gradesTbl AS g2 WHERE g2.studentId = g1.studentId AND g2.testDate BETWEEN "01/01/2008" AND "20/06/2008");
Но было бы лучше выбрать из таблицы students
, которая, как я полагаю, у вас есть, и studentId
в gradesTbl
ссылках ее id
:
SELECT s.studentId
FROM students AS s
WHERE
EXISTS (SELECT 1 FROM gradesTbl AS g WHERE g.studentId = s.studentId AND g.testDate BETWEEN "01/09/2007" AND "31/12/2007")
AND
EXISTS (SELECT 1 FROM gradesTbl AS g WHERE g.studentId = s.studentId AND g.testDate BETWEEN "01/01/2008" AND "20/06/2008");
Примечание:
Даты в Access — это не текст, а дата-время:
BETWEEN #2007/09/01# AND #2007/12/31#
BETWEEN #2008/01/01# AND #2008/06/20#
Комментарии:
1. Молодец, что правильно интерпретировал вопрос! Я внес небольшое редактирование, чтобы, надеюсь, устранить путаницу, которую оно создает.
Ответ №2:
Вы можете использовать агрегацию:
SELECT studentId
FROM gradesTbl
GROUP BY studentId
HAVING SUM(IIF(testDate BETWEEN "01/09/2007" AND "31/12/2007", 1, 0) > 0 AND
SUM(IIF(testDate BETWEEN "01/01/2008" AND "20/06/2008", 1, 0) > 0;
Каждое предложение в агрегации подсчитывает количество тестов, которые каждый учащийся проходит за указанный период. > 0
Возвращаются только учащиеся, которые прошли хотя бы один тест.
Ответ №3:
Вы также можете выполнить это, используя inner joins
подзапросы on, например:
select distinct t.studentid
from
(
gradestbl t inner join
(select distinct t.studentid from gradestbl t where t.testdate between #2007-09-01# and #2007-12-31#) q1
on t.studentid = q1.studentid
)
inner join
(select distinct t.studentid from gradestbl t where t.testdate between #2008-01-01# and #2008-06-20#) q2
on t.studentid = q2.studentid
Ответ №4:
В Access разделителем дат является #
знак.
Также логический оператор здесь должен быть OR
.
Итак, правильный запрос
SELECT studentId
FROM gradesTbl
WHERE testDate BETWEEN #01/09/2007# AND #31/12/2007#
OR testDate BETWEEN #01/01/2008# AND #20/06/2008#;
Поскольку оценка НИКОГДА не может отвечать обоим условиям, если вы хотите, чтобы учащиеся проходили тесты в оба периода, вам нужно будет сгруппировать свои данные.
SELECT studentId,
sum(iif(testDate BETWEEN #01/09/2007# AND #31/12/2007#;1;0)) period1
sum(iif(testDate BETWEEN #01/01/2008# AND #20/06/2008#;1;0)) period2
FROM gradesTbl
GROUP BY studentId
HAVING sum(iif(testDate BETWEEN #01/09/2007# AND #31/12/2007#;1;0)) > 0
AND sum(iif(testDate BETWEEN #01/01/2008# AND #20/06/2008#;1;0)) > 0
Примечание: не проверено — возможно, вам придется заменить некоторые «;» на «,» в зависимости от ваших региональных настроек.
Комментарии:
1. Вопрос в следующем: «Мне нужно показать студенческие удостоверения, которые сдавали тест в период с 01/09/2007 по 31/12/2007 и с 01/01/2008 по 20/06/2008″
2. @forpas ты прав, плохо. Но я пока оставлю свой ответ как есть, на случай, если проблема плохо сформулирована 🙂 Я надеюсь, что OP прояснит