Выполнение вычислений с использованием нескольких вложенных элементов в SQL - PullRequest
0 голосов
/ 01 июня 2011

Есть ли способ написать этот SQL-запрос на SQL?

select (select count(*) from a) / (select count(*) from b) as ratio;

Я сделал очевидное:

DB.fetch("select (select count(*) from a) / (select count(*) from b) as ratio")

но мне интересно, есть ли ещеидиоматический способ SQL сделать это.

Ответы [ 3 ]

2 голосов
/ 01 июня 2011

В настоящее время Sequel :: Dataset не может использовать все методы, которые могут использовать другие подклассы Sequel :: Expression, хотя, вероятно, он сможет обрабатывать по крайней мере некоторые из них.Вы можете использовать расширение sql_expr, поставляемое с Sequel, для обработки этого:

Sequel.extension :sql_expr
DB.select((DB[:a].select{count(:*){}}.sql_expr /
  DB[:b].select{count(:*){}}).as(:ratio))
# SELECT ((SELECT count(*) FROM a) /
#   (SELECT count(*) FROM b)) AS ratio
1 голос
/ 01 июня 2011
Declare @A int = (select count(*) from a);
Declare @B int = (select count(*) from b);

select convert(decimal(15,3), @A) / convert(decimal(15,3), @B) as Ratio
0 голосов
/ 01 июня 2011

Не уверен, что может сделать меня более идиоматичным, чем это. Ваш запрос кажется прекрасно. Какой бы ни была замена, она была бы, по меньшей мере, более многословной и не обязательно более ясной. (Я имею в виду, это может быть так же ясно и идиоматично, как и ваш запрос).

Но если вы настаиваете, вот возможный вариант:

SELECT a.cnt / b.cnt AS ratio
FROM
  (SELECT COUNT(*) FROM a) a (cnt),
  (SELECT COUNT(*) FROM b) b (cnt)

Может быть одна проблема. Вы делите целое число на целое число. Некоторые серверы баз данных выполняют целочисленное деление в таких случаях, что может привести к неожиданному результату. Например, 90 / 100 даст 0, а 2000 / 1001 приведет к 1.

Чтобы решить эту проблему, необходимо выполнить деление на нецелые числа. Достаточно преобразовать только один из операндов в нецелочисленный числовой тип, чтобы результат был более осмысленным. Вы можете использовать явное преобразование, как продемонстрировал @ hamlin11 , или вы можете преобразовать неявно, как это:

SELECT a.cnt * 1.0 / b.cnt AS ratio
FROM
  (SELECT COUNT(*) FROM a) a (cnt),
  (SELECT COUNT(*) FROM b) b (cnt)

Или, применяя непосредственно к вашему скрипту:

select (select count(*) from a) * 1.0 / (select count(*) from b) as ratio;
...