SQL: повторите результирующую строку несколько раз и пронумеруйте строки

Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException вообще.

См. также: A хороший список лучших практик

Я бы добавил, очень важно, хорошо использовать модификатор final. Использование "окончательной" модификатор, когда это применимо в Java

Сводка:

  1. Используйте модификатор final для обеспечения хорошей инициализации.
  2. Избегайте возврата null в методы, например, при возврате пустых коллекций.
  3. Использовать аннотации @NotNull и @Nullable
  4. Быстрое завершение работы и использование утверждений, чтобы избежать распространения нулевых объектов через все приложение, когда они не должен быть пустым.
  5. Сначала используйте значения с известным объектом: if("knownObject".equals(unknownObject)
  6. Предпочитают valueOf() поверх toString ().
  7. Используйте null safe StringUtils StringUtils.isEmpty(null).

24
задан cygri 3 May 2012 в 00:57
поделиться

4 ответа

Для MySQL используйте бедный человек generate_series , который делается через представления. MySQL - единственная СУБД среди большой четверки , у которой нет функции CTE.

На самом деле вы можете использовать эту технику в базе данных, которая поддерживает просмотр. Таким образом, это практически вся база данных

Техника генерации здесь: http://use-the-index-luke.com/blog/2011-07-30/mysql-row-generator#mysql_generator_code

Единственная незначительная модификация, которую мы сделали, - мы заменили битовую ( сдвиг влево и битовую или ) оригинальную технику простым умножением и сложением соответственно; поскольку у сервера Sql и Oracle нет оператора сдвига влево.

Эта абстракция гарантированно на 99% работает на всех базах данных, кроме Oracle; Oracle SELECT не может функционировать без какой-либо таблицы, для этого нужно выбрать фиктивную таблицу, Oracle уже предоставил одну, она называется DUAL table. Переносимость базы данных - несбыточная мечта: -)

Вот абстрагированные представления, работающие на всех RDBMS, лишенные побитовых операций (которые в любом случае не являются необходимостью в этом сценарии) и нюансы функций (мы удаляем OR REPLACE на CREATE VIEW только Postgresql и MySQL поддерживают их) из всех основных баз данных.

Предупреждение Oracle: просто ставьте FROM DUAL после каждого SELECT выражения

CREATE VIEW generator_16
AS SELECT 0 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   UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL
   SELECT 12  UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL 
   SELECT 15;

CREATE VIEW generator_256
AS SELECT ( ( hi.n * 16 ) + lo.n ) AS n
     FROM generator_16 lo, generator_16 hi;

CREATE VIEW generator_4k
AS SELECT ( ( hi.n * 256 ) + lo.n ) AS n
     FROM generator_256 lo, generator_16 hi;

CREATE VIEW generator_64k
AS SELECT ( ( hi.n * 256 ) + lo.n ) AS n
     FROM generator_256 lo, generator_256 hi;

CREATE VIEW generator_1m
AS SELECT ( ( hi.n * 65536 ) + lo.n ) AS n
     FROM generator_64k lo, generator_16 hi;

Затем используйте этот запрос:

SELECT t.value, t.cnt, i.n
FROM tbl t
JOIN generator_64k i 
ON i.n between 1 and t.cnt
order by t.value, i.n

Postgresql: http: //www.sqlfiddle.com/#!1/1541d/1

Oracle: http://www.sqlfiddle.com/#!4/26c05/1

Сервер Sql: http://www.sqlfiddle.com/#!6/84bee/1

MySQL: http: //www.sqlfiddle. ком / #! 2 / 78f5b / 1

21
ответ дан Community 3 May 2012 в 00:57
поделиться

MySQL - это действительно IE в мире баз данных, и он настолько сдержанный, когда речь заходит о стандартах и ​​возможностях.

Работает на всех основных СУБД, кроме MySQL:

with 
-- Please add this on Postgresql:
-- RECURSIVE
tbl_populate(value, cnt, ndx) as
(
  select value, cnt, 1 from tbl

  union all

  select t.value, t.cnt, tp.ndx + 1
  from tbl t
  join tbl_populate tp 
  on tp.value = t.value  
  and tp.ndx + 1 <= t.cnt
)
select * from tbl_populate
order by cnt, ndx

SQL Server: http://www.sqlfiddle.com/#!6/911a9/1

Oracle: http://www.sqlfiddle.com/#!4/198cd/1

Postgresql: http://www.sqlfiddle.com/#! 1 / 0b03d / 1

7
ответ дан Michael Buen 3 May 2012 в 00:57
поделиться

Создайте таблицу чисел - ее определение может незначительно отличаться в зависимости от платформы (это для SQL Server):

CREATE TABLE Numbers(Number INT PRIMARY KEY);

INSERT Numbers 
SELECT TOP 1000 ROW_NUMBER() OVER (ORDER BY name)
FROM sys.all_columns;

Теперь этот temp также является SQL Server, но демонстрирует синтаксис соединения, который должен быть действительным по указанным вами СУБД (хотя, признаюсь, я их не использую, поэтому не могу проверить):

DECLARE @foo TABLE(value VARCHAR(32), [count] INT);

INSERT @foo SELECT 'foo', 1
UNION ALL SELECT 'bar', 3
UNION ALL SELECT 'baz', 2;

SELECT f.value, f.[count], [index] = n.Number
FROM @foo AS f, Numbers AS n
WHERE n.Number <= f.[count];

Результаты (опять же, SQL Server):

value | count | index
------+-------+------
foo   |     1 |     1
bar   |     3 |     1
bar   |     3 |     2
bar   |     3 |     3
baz   |     2 |     1
baz   |     2 |     2
4
ответ дан Aaron Bertrand 3 May 2012 в 00:57
поделиться

Простым JOIN вы можете достичь цели повторения записей n раз.
Следующий запрос повторяет каждую запись 20 раз.

SELECT  TableName.*
FROM    TableName
JOIN    master.dbo.spt_values on type = 'P' and number < 20


Примечание для master.dbo.spt_values on type = 'P':
Эта таблица используется для получения серии чисел, жестко закодированных в ней при условии type='P'.

1
ответ дан Siyavash Hamdi 3 May 2012 в 00:57
поделиться
Другие вопросы по тегам:

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