Сложный оператор SQL более 3 таблиц - PullRequest
2 голосов
/ 12 сентября 2009

У меня есть 3 разные таблицы транзакций, которые очень похожи, но имеют небольшие различия. Это связано с тем, что существует 3 различных типа транзакций; в зависимости от типа транзакции столбцы меняются, поэтому чтобы получить их в 3NF, мне нужно, чтобы они были в отдельных таблицах (верно?).

Как пример:
t1: дата, пользователь, сумма

t2: дата, пользователь, который, сумма

t3: дата, пользователь, на что, количество

Теперь мне нужен запрос, который собирается получить все транзакции в каждой таблице для одного и того же пользователя, что-то вроде

выберите * из t1, t2, t3, где user = 'me'; (что, конечно, не работает).

Я изучаю операторы JOIN, но не нашел правильного способа сделать это. Спасибо.

РЕДАКТИРОВАТЬ: На самом деле мне нужны все столбцы из каждой таблицы, а не только те, которые одинаковы.


РЕДАКТИРОВАТЬ # 2: Да, наличие транзакции тип не нарушает 3NF, конечно, так что, возможно, мой дизайн совершенно не так. Вот что действительно происходит (это альтернативная валютная система):
- Операции между пользователями, как взаимный кредит. Таким образом, единицы меняются между пользователями.
- Инвентаризации - это физические вещи, внесенные в систему; пользователь получает единицы для этого.
- Потребления - это физические вещи, которые потребляются; пользователь должен платить за это.

|--------------------------------------------------------------------------|
|  type     |  transactions       |  inventarizations  |  consumations     |
|--------------------------------------------------------------------------|
|  columns  |  date               |  date              |  date             |
|           |  creditor(FK user)  |  creditor(FK user) |                   |
|           |  debitor(FK user)   |                    |  debitor(FK user) |
|           |  service(FK service)|                    |                   |
|           |                     |  asset(FK asset)   |  asset(FK asset)  |
|           |  amount             |  amount            |  amount           |
|           |                     |                    |  price            |
|--------------------------------------------------------------------------|

(Обратите внимание, что «сумма» указана в разных единицах; это записи и расчеты по этим суммам. Вне рамок объяснения, почему, но это поля).
Таким образом, вопрос меняется на « Может / должно ли это быть в одной таблице или быть несколькими таблицами (как у меня сейчас)? " Мне нужен ранее описанный оператор SQL для отображения текущих балансов.


(Должно ли это теперь стать новым вопросом или это нормально для редактирования?).

РЕДАКТИРОВАТЬ # 3: Поскольку РЕДАКТИРОВАНИЕ # 2 фактически преобразовывает это в новый вопрос, я также решил опубликовать новый вопрос . (Надеюсь, это нормально?).

Ответы [ 7 ]

5 голосов
/ 12 сентября 2009

Вы можете указать значения по умолчанию как константы в операторах выбора для столбцов, в которых у вас нет данных;

так

SELECT Date, User, Amount, 'NotApplicable' as Who, 'NotApplicable' as What from t1 where user = 'me'
UNION
SELECT Date, User, Amount, Who, 'NotApplicable' from t2 where user = 'me'
UNION
SELECT Date, User, Amount, 'NotApplicable', What from t3 where user = 'me'

, который предполагает, что Who и What являются столбцами строкового типа. Вы также можете использовать Null, но необходим какой-то заполнитель.

Я думаю, что размещение вашей дополнительной информации в отдельной таблице и хранение всех транзакций в одной таблице будет работать для вас лучше, если только я не пропустил некоторые другие детали.

1 голос
/ 12 сентября 2009

Я думаю, что мясо вашего вопроса здесь:

в зависимости от типа транзакции столбцы меняются, поэтому чтобы получить их в 3NF, мне нужно, чтобы они были в отдельных таблицах (верно?).

Я не эксперт по 3NF, но я бы подошел к вашей схеме немного иначе (что могло бы немного прояснить ваш SQL).

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

User
----
id, user info (username, etc)

Who
---
id, who info

What
----
id, what info

Transaction
-----------
id, date, amount, user_id, who_id, what_id

Разбор слов вашего внешнего ключа будет зависеть от реализации базы данных, но это немного яснее (и расширяется).

0 голосов
/ 12 сентября 2009
select *
from (
    select user from t1
    union
    select user from t2
    union
    select user from t3
) u
left outer join t1 on u.user=t1.user
left outer join t2 on u.user=t2.user
left outer join t3 on u.user=t3.user
0 голосов
/ 12 сентября 2009

Как насчет того, чтобы просто оставить ненужные столбцы пустыми и добавить столбец TransactionType? Это приведет к простой инструкции SELECT.

0 голосов
/ 12 сентября 2009

Или вы можете «подкласс» их

  Create Table Transaction
  ( 
     TransactionId Integer Primary Key Not Null,
     TransactionDateTime dateTime Not Null,
     TransactionType Integer Not Null, 
     -- Othe columns all transactions Share
  )

  Create Table Type1Transactions
  {
     TransactionId Integer PrimaryKey Not Null,
     // Type 1 specific columns
  }
  ALTER TABLE Type1Transactions  WITH CHECK ADD  CONSTRAINT 
   [FK_Type1Transaction_Transaction] FOREIGN KEY([TransactionId])
    REFERENCES [Transaction] ([TransactionId])

Повторите для других типов транзакций ...

0 голосов
/ 12 сентября 2009

Как будет выглядеть схема результата? - Если вам нужны только минимальные столбцы, которые есть во всех 3 таблицах, то это просто, вы просто ОБЪЕДИНИТЕ результаты:

SELECT Date, User, Amount from t1 where user = 'me'
UNION
SELECT Date, User, Amount from t2 where user = 'me'
UNION
SELECT Date, User, Amount from t3 where user = 'me'
0 голосов
/ 12 сентября 2009

Вы должны рассматривать STI как «архитектура» (наследование одной таблицы). То есть поместите все разные столбцы в одну таблицу и поместите их под одним индексом.

Кроме того, вы можете добавить индексы к другим столбцам, которые вы делаете выбор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...