超过3个表的棘手SQL语句

时间:2009-09-11 20:20:55

标签: sql mysql join

我有3个不同的交易表,看起来非常相似,但略有不同。这是因为有3种不同的交易类型;取决于列更改的事务类型,因此要在3NF中获取它们,我需要将它们放在单独的表中(对吗?)。

举个例子:
T1: 日期,用户,量

T2: 日期,用户,谁,量

T3: 日期,用户,什么,量

现在我需要一个查询,它将为每个表中的同一个用户提供所有交易,例如

select * from t1,t2,t3 where user ='me'; (当然这不起作用)。

我正在研究JOIN语句,但没有正确的方法来做到这一点。感谢。

编辑:其实我需要每张表中的所有列,而不仅仅是那些相同的列。


编辑#2:是的,当然,拥有transaction_type并不会破坏3NF - 所以也许我的设计完全错了。这是真正发生的事情(它是另一种货币体系):
- 交易在用户之间,如相互信用。因此,单位在用户之间交换 - Inventarizations是带入系统的物理内容;用户获得此单位。
- 消耗是消耗的物质;用户必须为此付费。

|--------------------------------------------------------------------------|
|  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实际上将此转换为新问题,我还决定发布a new question。 (我希望这没关系?)。

7 个答案:

答案 0 :(得分:5)

您可以在没有数据的列的select语句中为默认值提供默认值;

所以

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 :(得分:1)

我认为你问题的关键在于:

  

取决于列更改的事务类型,因此要在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

您的外键约束措辞会因数据库实施而异,但这有点清晰(可扩展)。

答案 2 :(得分:0)

您应该考虑STI“架构”(单表继承)。即将所有不同的列放在一个表中,并将它们全部放在一个索引下。

此外,您可能希望将索引添加到您正在选择的其他列中。

答案 3 :(得分:0)

结果架构会是什么样子? - 如果你只想要所有3个表中的最小列,那么很容易,你只需要UNION结果:

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'

答案 4 :(得分:0)

或者你可以'SubClass'他们

  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])

重复其他类型的交易......

答案 5 :(得分:0)

如果只是将不必要的列留空并添加TransactionType列呢?这将导致一个简单的SELECT语句。

答案 6 :(得分:-1)

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