Что вы должны сделать:
Добавить конструктор в ваш суперкласс:
public Superclass {
public SuperClass(String flavour) {
// super class constructor
this.flavour = flavour;
}
}
В классе Crisps:
public Crisps(String flavour, int quantity) {
super(flavour); // send flavour to the super class constructor
this.quantity = quantity;
}
& nbsp;
Комментарии
Некоторые комментарии к вашему вопросу:
«В суперклассе я инициализировал поле с помощью«
private String flavour;
не является инициализацией, это декларация. Инициализация - это когда вы устанавливаете значение.
«Я получаю сообщение об ошибке» имеет личный доступ в суперклассе », но я считаю, что это не имеет значения, поскольку я вызываю метод доступа, который возвращает его поле? "
Когда вы вызываете аксессуар (aka getter), это нормально - зависит от видимости геттера. Проблема в вашем коде:
this.flavour =
, потому что аромат не является полем, объявленным в классе Crisps, но в классе ужина, поэтому вы не можете делать прямой доступ. вы должны использовать мое предложение или объявить сеттера в суперклассе:
public void setFlavour(String flavour) {
this.flavour = flavour;
}
Затем вы можете использовать его в дочернем классе:
public Crisps(String flavour, int quantity) {
this.quantity = quantity;
super.setFlavour(flavour);
}
Это решение не использует циклы, процедуры или временные таблицы. Подзапрос генерирует даты в течение последних тысяч дней и может быть расширен, чтобы идти как можно дальше или вперед по вашему желанию.
select a.Date
from (
select curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY as Date
from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
) a
where a.Date between '2010-01-20' and '2010-01-24'
Выход:
Date
----------
2010-01-24
2010-01-23
2010-01-22
2010-01-21
2010-01-20
Примечания к производительности
Тестирование здесь , производительность на удивление хороша: вышеупомянутый запрос занимает 0,0009 сек.
Если мы расширим подзапрос, чтобы создать ок. 100000 номеров (и, следовательно, даты дат 274 года), он работает в 0,0458 сек.
Кстати, это очень портативный метод, который работает с большинством баз данных с небольшими корректировками.
, если вам нужен список дат между двумя датами:
create table #dates ([date] smalldatetime)
while @since < @to
begin
insert into #dates(dateadd(day,1,@since))
set @since = dateadd(day,1,@since)
end
select [date] from #dates
* скрипка здесь: http://sqlfiddle.com/#!6/9eecb/3469
, если вам понадобится больше двух дней, вам понадобится таблица.
, затем
select from days.day, count(mytable.field) as fields from days left join mytable on day=date where date between x and y;
Короче принятого ответа, та же идея:
(SELECT TRIM('2016-01-05' + INTERVAL a + b DAY) date
FROM
(SELECT 0 a UNION SELECT 1 a UNION SELECT 2 UNION SELECT 3
UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7
UNION SELECT 8 UNION SELECT 9 ) d,
(SELECT 0 b UNION SELECT 10 UNION SELECT 20
UNION SELECT 30 UNION SELECT 40) m
WHERE '2016-01-05' + INTERVAL a + b DAY <= '2016-01-21')
Принятый ответ не работал для PostgreSQL (синтаксическая ошибка в или рядом с «a»).
Как вы это делаете в PostgreSQL, используется функция generate_series
, то есть:
SELECT day::date
FROM generate_series('2010-01-20', '2010-01-24', INTERVAL '1 day') day;
day
------------
2010-01-20
2010-01-21
2010-01-22
2010-01-23
2010-01-24
(5 rows)
Это хорошая идея, чтобы генерировать эти даты на лету. Тем не менее, я не чувствую себя комфортно для этого с довольно большим диапазоном, поэтому я получил следующее решение:
CREATE TABLE DatesNumbers (
i MEDIUMINT NOT NULL,
PRIMARY KEY (i)
)
COMMENT='Used by Dates view'
;
INSERT INTO DatesNumbers
SELECT
a.i + (10 * b.i) + (100 * c.i) + (1000 * d.i) + (10000 * e.i) - 59999 AS i
FROM
(SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS a
, (SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS b
, (SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS c
, (SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS d
, (SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS e
;
SELECT
i
, CURRENT_DATE() + INTERVAL i DAY AS Date
FROM
DatesNumbers
Вот и все.
WHERE i < 0
или WHERE i > 0
(PK) Используя рекурсивное выражение общей таблицы (CTE), вы можете создать список дат, а затем выбрать из него. Очевидно, вы обычно не хотели бы создавать три миллиона дат, поэтому это просто иллюстрирует возможности. Вы можете просто ограничить диапазон дат внутри CTE и опустить предложение where из оператора select с помощью CTE.
with [dates] as (
select convert(datetime, '1753-01-01') as [date] --start
union all
select dateadd(day, 1, [date])
from [dates]
where [date] < '9999-12-31' --end
)
select [date]
from [dates]
where [date] between '2013-01-01' and '2013-12-31'
option (maxrecursion 0)
В Microsoft SQL Server 2005 генерация списка CTE всех возможных дат заняла 1: 08. Генерация столетий заняла менее секунды.
улучшилось с буднего дня, присоединившись к специальной праздничной таблице microsoft MSSQL 2012 для таблицы даты powerpivot https://gist.github.com/josy1024/cb1487d66d9e0ccbd420bc4a23b6e90e
with [dates] as (
select convert(datetime, '2016-01-01') as [date] --start
union all
select dateadd(day, 1, [date])
from [dates]
where [date] < '2018-01-01' --end
)
select [date]
, DATEPART (dw,[date]) as Wochentag
, (select holidayname from holidaytable
where holidaytable.hdate = [date])
as Feiertag
from [dates]
where [date] between '2016-01-01' and '2016-31-12'
option (maxrecursion 0)
Как было сказано (или, по крайней мере, намечено) во многих замечательных ответах, уже заданных, эта проблема легко решается после того, как у вас есть набор чисел для работы.
Примечание: / g0] Ниже приводится T-SQL, но это просто моя конкретная реализация общих понятий, уже упомянутых здесь и в Интернете в целом. Это должно быть относительно просто преобразовать код в ваш выбор по выбору.
Как? Рассмотрим этот запрос:
SELECT DATEADD(d, N, '0001-01-22')
FROM Numbers -- A table containing the numbers 0 through N
WHERE N <= 5;
Вышеуказанное дает диапазон дат 1/22/0001 - 1/27/0001 и является чрезвычайно тривиальным. В приведенном выше запросе есть две ключевые части информации: дата начала 0001-01-22
и смещение в 5
. Если мы объединим эти две части информации, мы, очевидно, имеем дату окончания. Таким образом, учитывая две даты, генерация диапазона может быть разбита так:
-- Returns 125
SELECT ABS(DATEDIFF(d, '2014-08-22', '2014-12-25'))
Используя ABS()
, здесь обеспечивается, что -- Returns the numbers 0-2
SELECT N = ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) - 1
FROM(SELECT 'A' AS S UNION ALL SELECT 'A' UNION ALL SELECT 'A')
Обратите внимание, что нам действительно не важно, что мы выбираем здесь FROM
. Нам просто нужен набор для работы, чтобы мы подсчитали количество строк в нем. Я лично использую TVF, некоторые используют CTE, другие используют таблицу чисел, вы получаете идею. Я рекомендую использовать наиболее эффективное решение, которое вы также понимаете. Объединение этих двух методов решит нашу проблему:
DECLARE @date1 DATE = '9001-11-21';
DECLARE @date2 DATE = '9001-11-23';
SELECT D = DATEADD(d, N, @date1)
FROM (
SELECT N = ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) - 1
FROM (SELECT 'A' AS S UNION ALL SELECT 'A' UNION ALL SELECT 'A') S
) Numbers
WHERE N <= ABS(DATEDIFF(d, @date1, @date2));
Вышеприведенный пример - ужасный код, но демонстрирует, как все объединяется.
More Fun
Мне нужно много чего делать, поэтому я инкапсулировал логику в два TVF. Первый генерирует ряд чисел, а второй использует эту функцию для создания диапазона дат. Математика заключается в том, чтобы гарантировать, что порядок ввода не имеет значения, и потому, что я хотел использовать полный диапазон чисел, доступных в GenerateRangeSmallInt
.
Следующая функция занимает ~ 16 мс времени процессора, чтобы вернуть максимальный диапазон из 65536 дат.
CREATE FUNCTION dbo.GenerateRangeDate (
@date1 DATE,
@date2 DATE
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN (
SELECT D = DATEADD(d, N + 32768, CASE WHEN @date1 <= @date2 THEN @date1 ELSE @date2 END)
FROM dbo.GenerateRangeSmallInt(-32768, ABS(DATEDIFF(d, @date1, @date2)) - 32768)
);
GO
CREATE FUNCTION dbo.GenerateRangeSmallInt (
@num1 SMALLINT = -32768
, @num2 SMALLINT = 32767
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN (
WITH Numbers(N) AS (
SELECT N FROM(VALUES
(1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 16
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 32
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 48
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 64
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 80
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 96
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 112
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 128
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 144
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 160
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 176
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 192
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 208
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 224
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 240
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 256
) V (N)
)
SELECT TOP(ABS(CAST(@num1 AS INT) - CAST(@num2 AS INT)) + 1)
N = ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) + CASE WHEN @num1 <= @num2 THEN @num1 ELSE @num2 END - 1
FROM Numbers A
, Numbers B
);
попробуйте это.
SELECT TO_DATE('20160210','yyyymmdd') - 1 + LEVEL AS start_day
from DUAL
connect by level <= (TO_DATE('20160228','yyyymmdd') + 1) - TO_DATE('20160210','yyyymmdd') ;
Процедура + временная таблица:
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `days`(IN dateStart DATE, IN dateEnd DATE)
BEGIN
CREATE TEMPORARY TABLE IF NOT EXISTS date_range (day DATE);
WHILE dateStart <= dateEnd DO
INSERT INTO date_range VALUES (dateStart);
SET dateStart = DATE_ADD(dateStart, INTERVAL 1 DAY);
END WHILE;
SELECT * FROM date_range;
DROP TEMPORARY TABLE IF EXISTS date_range;
END
Версия SQLite решения RedFilters top
select d.Date
from (
select
date(julianday('2010-01-20') + (a.a + (10 * b.a) + (100 * c.a))) as Date
from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
) d
where
d.Date between '2010-01-20' and '2010-01-24'
order by d.Date
set language 'SPANISH'
DECLARE @table table(fechaDesde datetime , fechaHasta datetime )
INSERT @table VALUES('20151231' , '20161231');
WITH x AS
(
SELECT DATEADD( m , 1 ,fechaDesde ) as fecha FROM @table
UNION ALL
SELECT DATEADD( m , 1 ,fecha )
FROM @table t INNER JOIN x ON DATEADD( m , 1 ,x.fecha ) <= t.fechaHasta
)
SELECT LEFT( CONVERT( VARCHAR, fecha , 112 ) , 6 ) as Periodo_Id
,DATEPART ( dd, DATEADD(dd,-(DAY(fecha)-1),fecha)) Num_Dia_Inicio
,DATEADD(dd,-(DAY(fecha)-1),fecha) Fecha_Inicio
,DATEPART ( mm , fecha ) Mes_Id
,DATEPART ( yy , fecha ) Anio
,DATEPART ( dd, DATEADD(dd,-(DAY(DATEADD(mm,1,fecha))),DATEADD(mm,1,fecha))) Num_Dia_Fin
,DATEADD(dd,-(DAY(DATEADD(mm,1,fecha))),DATEADD(mm,1,fecha)) ultimoDia
,datename(MONTH, fecha) mes
,'Q' + convert(varchar(10), DATEPART(QUARTER, fecha)) Trimestre_Name
FROM x
OPTION(MAXRECURSION 0)
Для Oracle мое решение:
select trunc(sysdate-dayincrement, 'DD')
from dual, (select level as dayincrement
from dual connect by level <= 30)
Sysdate можно изменить на определенную дату, а номер уровня можно изменить, чтобы указать больше дат.
Вот пример
У нас есть даты в одной таблице
Название таблицы: «testdate»
STARTDATE ENDDATE
10/24/2012 10/24/2012
10/27/2012 10/29/2012
10/30/2012 10/30/2012
Требовать Результат:
STARTDATE
10/24/2012
10/27/2012
10/28/2012
10/29/2012
10/30/2012
Решение:
WITH CTE AS
(SELECT DISTINCT convert(varchar(10),StartTime, 101) AS StartTime,
datediff(dd,StartTime, endTime) AS diff
FROM dbo.testdate
UNION ALL SELECT StartTime,
diff - 1 AS diff
FROM CTE
WHERE diff<> 0)
SELECT DISTINCT DateAdd(dd,diff, StartTime) AS StartTime
FROM CTE
Объяснение: CTE Рекурсивное пояснение запроса
SELECT DISTINCT convert(varchar(10), StartTime, 101) AS StartTime, datediff(dd, StartTime, endTime) AS diff FROM dbo.testdate
Объяснение: firstcolumn - «startdate», второй столбец - разность начало и конец даты в днях, и это будет рассматриваться как столбец «diff» UNION ALL SELECT StartTime, diff-1 AS diff FROM CTE WHERE diff<>0
Объяснение: Союз все наследует результат вышеуказанного запроса до результата имеет значение null, поэтому результат «StartTime» наследуется от сгенерированного запроса CTE, а от diff, уменьшения - 1, поэтому он выглядит как 3, 2 и 1 до 0 Например,
STARTDATE DIFF
10/24/2012 0
10/27/2012 0
10/27/2012 1
10/27/2012 2
10/30/2012 0
Спецификация результата
STARTDATE Specification
10/24/2012 --> From Record 1
10/27/2012 --> From Record 2
10/27/2012 --> From Record 2
10/27/2012 --> From Record 2
10/30/2012 --> From Record 3
SELECT DISTINCT DateAdd(dd,diff, StartTime) AS StartTime FROM CTE
Она добавит день «diff» в «startdate», поэтому результат Shou ld будет ниже Результат
STARTDATE
10/24/2012
10/27/2012
10/28/2012
10/29/2012
10/30/2012
Старое решение школы для этого без цикла / курсора состоит в создании таблицы NUMBERS
, которая имеет один столбец Integer со значениями, начинающимися с 1.
CREATE TABLE `example`.`numbers` (
`id` int(10) unsigned NOT NULL auto_increment,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Вам нужно заполнить таблицу с достаточным количеством записей, чтобы удовлетворить ваши потребности:
INSERT INTO NUMBERS (id) VALUES (NULL);
После того, как у вас есть таблица NUMBERS
, вы можете использовать:
SELECT x.start_date + INTERVAL n.id-1 DAY
FROM NUMBERS n
JOIN (SELECT STR_TO_DATE('2010-01-20', '%Y-%m-%d') AS start_date
FROM DUAL) x
WHERE x.start_date + INTERVAL n.id-1 DAY <= '2010-01-24'
Абсолютное низкотехнологичное решение be:
SELECT STR_TO_DATE('2010-01-20', '%Y-%m-%d')
FROM DUAL
UNION ALL
SELECT STR_TO_DATE('2010-01-21', '%Y-%m-%d')
FROM DUAL
UNION ALL
SELECT STR_TO_DATE('2010-01-22', '%Y-%m-%d')
FROM DUAL
UNION ALL
SELECT STR_TO_DATE('2010-01-23', '%Y-%m-%d')
FROM DUAL
UNION ALL
SELECT STR_TO_DATE('2010-01-24', '%Y-%m-%d')
FROM DUAL
Чтобы генерировать списки дат или цифр, чтобы ЛЕВАЯ ВСТУПЛЕНИЕ на. Вы должны были бы это сделать, чтобы увидеть, где есть пробелы в данных, потому что вы LEFT JOINING в список секвенциальных данных - нулевые значения станут очевидными там, где существуют пробелы.
DUAL
поддерживается Oracle и MySQL для использования в качестве таблицы stand-in в предложении FROM
. Он не существует, выбор значений из него будет возвращать все значения. Идея заключалась в том, чтобы иметь stand-in, потому что для запроса SELECT требуется предложение FROM
, определяющее хотя бы одну таблицу.
– OMG Ponies
29 January 2010 в 00:17
Вот еще одна вариация, использующая представления:
CREATE VIEW digits AS
SELECT 0 AS digit UNION ALL
SELECT 1 UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5 UNION ALL
SELECT 6 UNION ALL
SELECT 7 UNION ALL
SELECT 8 UNION ALL
SELECT 9;
CREATE VIEW numbers AS
SELECT
ones.digit + tens.digit * 10 + hundreds.digit * 100 + thousands.digit * 1000 AS number
FROM
digits as ones,
digits as tens,
digits as hundreds,
digits as thousands;
CREATE VIEW dates AS
SELECT
SUBDATE(CURRENT_DATE(), number) AS date
FROM
numbers;
И тогда вы можете просто сделать (посмотрите, насколько она элегантна?):
SELECT
date
FROM
dates
WHERE
date BETWEEN '2010-01-20' AND '2010-01-24'
ORDER BY
date
Обновить
Стоит отметить, что вы сможете генерировать прошлые даты, начиная с текущей даты . Если вы хотите создать какой-либо диапазон дат (прошлый, будущий и промежуточный), вам придется использовать это представление вместо этого:
CREATE VIEW dates AS
SELECT
SUBDATE(CURRENT_DATE(), number) AS date
FROM
numbers
UNION ALL
SELECT
ADDDATE(CURRENT_DATE(), number + 1) AS date
FROM
numbers;
dates
, упомянутый выше, вычисляет даты, начинающиеся с текущей даты, поэтому вы не сможете получить даты, установленные в будущем. Ответ от @RedFilter страдает от того же дефекта дизайна. Однако я добавил обходной путь в свой ответ.
– Stéphane
22 December 2013 в 23:09
UNION
выглядят странно в одном выражении SQL.
– Stewart
6 September 2016 в 16:51
Запрос MSSQL
select datetable.Date
from (
select DATEADD(day,-(a.a + (10 * b.a) + (100 * c.a)),getdate()) AS Date
from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4
union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4
union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4
union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
) datetable
where datetable.Date between '2014-01-20' and '2014-01-24'
order by datetable.Date DESC
Выход
Date
-----
2014-01-23 12:35:25.250
2014-01-22 12:35:25.250
2014-01-21 12:35:25.250
2014-01-20 12:35:25.250
Для всех, кто хочет это как сохраненное представление (MySQL не поддерживает вложенные операторы select в представлениях):
create view zero_to_nine as
select 0 as n union all
select 1 union all
select 2 union all
select 3 union all
select 4 union all
select 5 union all
select 6 union all
select 7 union all
select 8 union all
select 9;
create view date_range as
select curdate() - INTERVAL (a.n + (10 * b.n) + (100 * c.n)) DAY as date
from zero_to_nine as a
cross join zero_to_nine as b
cross join zero_to_nine as c;
Затем вы можете сделать
select * from date_range
, чтобы get
date
---
2017-06-06
2017-06-05
2017-06-04
2017-06-03
2017-06-02
...
Хорошо .. Попробуйте следующее: http://www.devshed.com/c/a/MySQL/Delving-Deeper-into-MySQL-50/ http: // dev .mysql.com / doc / refman / 5.0 / ru / loop-statement.html http://www.roseindia.net/sql/mysql-example/mysql-loop.shtml
Используйте это, чтобы, скажем, создать временную таблицу, а затем сделать select * в таблице temp. Или выводить результаты по одному. То, что вы говорите, что вы хотите сделать, не может быть сделано с помощью инструкции SELECT , но это может быть выполнимо с вещами, специфичными для MySQL. Опять же, возможно, вам нужны курсоры: http://dev.mysql.com/doc/refman/5.0/en/cursors.html
thx Pentium10 - вы заставили меня присоединиться к stackoverflow :) - это мой портирование на msaccess - думаю, что он будет работать в любой версии:
SELECT date_value
FROM (SELECT a.espr1+(10*b.espr1)+(100*c.espr1) AS integer_value,
dateadd("d",integer_value,dateserial([start_year], [start_month], [start_day])) as date_value
FROM (select * from
(
select top 1 "0" as espr1 from MSysObjects
union all
select top 1 "1" as espr2 from MSysObjects
union all
select top 1 "2" as espr3 from MSysObjects
union all
select top 1 "3" as espr4 from MSysObjects
union all
select top 1 "4" as espr5 from MSysObjects
union all
select top 1 "5" as espr6 from MSysObjects
union all
select top 1 "6" as espr7 from MSysObjects
union all
select top 1 "7" as espr8 from MSysObjects
union all
select top 1 "8" as espr9 from MSysObjects
union all
select top 1 "9" as espr9 from MSysObjects
) as a,
(
select top 1 "0" as espr1 from MSysObjects
union all
select top 1 "1" as espr2 from MSysObjects
union all
select top 1 "2" as espr3 from MSysObjects
union all
select top 1 "3" as espr4 from MSysObjects
union all
select top 1 "4" as espr5 from MSysObjects
union all
select top 1 "5" as espr6 from MSysObjects
union all
select top 1 "6" as espr7 from MSysObjects
union all
select top 1 "7" as espr8 from MSysObjects
union all
select top 1 "8" as espr9 from MSysObjects
union all
select top 1 "9" as espr9 from MSysObjects
) as b,
(
select top 1 "0" as espr1 from MSysObjects
union all
select top 1 "1" as espr2 from MSysObjects
union all
select top 1 "2" as espr3 from MSysObjects
union all
select top 1 "3" as espr4 from MSysObjects
union all
select top 1 "4" as espr5 from MSysObjects
union all
select top 1 "5" as espr6 from MSysObjects
union all
select top 1 "6" as espr7 from MSysObjects
union all
select top 1 "7" as espr8 from MSysObjects
union all
select top 1 "8" as espr9 from MSysObjects
union all
select top 1 "9" as espr9 from MSysObjects
) as c
) as d)
WHERE date_value
between dateserial([start_year], [start_month], [start_day])
and dateserial([end_year], [end_month], [end_day]);
, на который ссылаются MSysObjects, просто потому, что для доступа нужен стол countin 'по крайней мере 1 запись, в условии from - любая таблица с не менее чем 1 записью.
DELIMITER $$
CREATE PROCEDURE GenerateRangeDates(IN dateStart DATE, IN dateEnd DATE)
BEGIN
CREATE TEMPORARY TABLE IF NOT EXISTS dates (day DATE);
loopDate: LOOP
INSERT INTO dates(day) VALUES (dateStart);
SET dateStart = DATE_ADD(dateStart, INTERVAL 1 DAY);
IF dateStart <= dateEnd
THEN ITERATE loopDate;
ELSE LEAVE loopDate;
END IF;
END LOOP loopDate;
SELECT day FROM dates;
DROP TEMPORARY TABLE IF EXISTS dates;
END
$$
-- Call procedure
call GenerateRangeDates(
now() - INTERVAL 40 DAY,
now()
);
UNION
наUNION ALL
- он тратит время на проверку дубликатов для удаления, которых не существует. Это слишком сложная ИМО, хотя, если вы собираетесь создавать набор результатов с помощью UNION, почему бы просто не указать дату и не сделать с ней? – OMG Ponies 28 January 2010 в 22:27