Использование неравных соединений - PullRequest
3 голосов
/ 27 марта 2009

Из всех тысяч запросов, которые я написал, я, вероятно, могу посчитать с одной стороны, сколько раз я использовал неэквиджойн. e.g.:

SELECT * FROM tbl1 INNER JOIN tbl2 ON tbl1.date > tbl2.date

И большинство из этих случаев, вероятно, было лучше решено с помощью другого метода. Есть ли какие-нибудь хорошие / умные способы использования неэквино, которые вы встречали в реальном мире?

Ответы [ 7 ]

2 голосов
/ 27 марта 2009

Битовые маски приходят на ум. На одном из моих заданий у нас были разрешения для конкретного пользователя или группы на «объект» (обычно соответствующий форме или классу в коде), хранящийся в базе данных. Вместо того, чтобы включать строку или столбец для каждого конкретного разрешения (чтение, запись, чтение других, запись других и т. Д.), Мы обычно присваиваем битовое значение каждому из них. Оттуда мы можем затем присоединиться, используя побитовые операторы, чтобы получить объекты с определенным разрешением.

1 голос
/ 14 июля 2013

Только что нашел еще одно интересное использование неравного соединения в книге учебных комплектов MCTS 70-433 (разработка баз данных SQL Server 2008). Дословно ниже.

Комбинируя производные таблицы с неравными объединениями, вы можете вычислять различные совокупные агрегаты. Следующий запрос возвращает текущую совокупность заказов для каждого продавца (мое примечание - со ссылкой на вездесущий образец базы данных AdventureWorks):

select
    SH3.SalesPersonID,
    SH3.OrderDate,
    SH3.DailyTotal,
    SUM(SH4.DailyTotal) RunningTotal
from
    (select SH1.SalesPersonID, SH1.OrderDate, SUM(SH1.TotalDue) DailyTotal
    from Sales.SalesOrderHeader SH1
    where SH1.SalesPersonID IS NOT NULL
    group by SH1.SalesPersonID, SH1.OrderDate) SH3
join
    (select SH1.SalesPersonID, SH1.OrderDate, SUM(SH1.TotalDue) DailyTotal
    from Sales.SalesOrderHeader SH1
    where SH1.SalesPersonID IS NOT NULL
    group by SH1.SalesPersonID, SH1.OrderDate) SH4
on SH3.SalesPersonID = SH4.SalesPersonID AND SH3.OrderDate >= SH4.OrderDate
group by SH3.SalesPersonID, SH3.OrderDate, SH3.DailyTotal
order by SH3.SalesPersonID, SH3.OrderDate

Производные таблицы используются для объединения всех заказов для продавцов, у которых более одного заказа за один день. Объединение по SalesPersonID гарантирует, что вы накапливаете строки только для одного продавца. Неравное объединение позволяет агрегату учитывать только те строки для продавца, где дата заказа раньше, чем дата заказа, которая в данный момент рассматривается в наборе результатов.

В этом конкретном примере неравное объединение создает вид суммы «скользящего окна» для столбца суточного итога в SH4.

1 голос
/ 27 марта 2009

Интеравалы целого дня в полях date_time:

date_time_field> = begin_date и date_time_field

1 голос
/ 27 марта 2009

Как насчет проверки перекрытий?

select ...
from   employee_assignments ea1
,      employee_assignments ea2
where  ea1.emp_id = ea2.emp_id
and    ea1.end_date >= ea2.start_date
and    ea1.start_date <= ea1.start_date
0 голосов
/ 27 марта 2009

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

Например, вы можете иметь таблицу Product и таблицу Customer. Гипотетически, если вы хотите показать список каждого продукта с каждым покупателем, вы можете сделать что-то вроде этого:

ВЫБРАТЬ * ОТ продукта р ПРИСОЕДИНИТЬСЯ Клиент c на p.SKU <> c.SSN

Это может быть полезно. Однако будьте осторожны, потому что он может создавать огромные наборы результатов.

0 голосов
/ 27 марта 2009

Если вы хотели получить все продукты, чтобы предложить их покупателю, и не хотите предлагать им продукты, которые у них уже есть:

SELECT
     C.customer_id,
     P.product_id
FROM
     Customers C
INNER JOIN Products P ON
     P.product_id NOT IN
          (
               SELECT
                    O.product_id
               FROM
                    Orders O
               WHERE
                    O.customer_id = C.customer_id
          )

Чаще всего, хотя, когда я использую неэквино, это потому, что я делаю какое-то ручное исправление данных. Например, бизнес говорит мне, что человеку в пользовательской таблице должны быть предоставлены все роли доступа, которых у него еще нет, и т. Д.

0 голосов
/ 27 марта 2009

дубликаты;

SELECT
  *
FROM
  table a, (
    SELECT
      id,
      min(rowid)
    FROM 
      table
    GROUP BY
      id
  ) b
WHERE
  a.id = b.id
  and a.rowid > b.rowid;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...