【问题标题】:Query to join multiple tables查询连接多个表
【发布时间】:2020-04-19 12:38:11
【问题描述】:

我有一个名为 Entity 的表,它只包含一个 ID int 作为主键。 我还有许多任务表(Task1, Task2, Task3, ...)。这些任务表有许多单独的列,但共有三列:

  1. 一列time_created datetime2(7),默认设置为getdate()
  2. 自己的ID intPK
  3. 外键ID_Entity(当然是Entity表的PK)。
CREATE TABLE [dbo].[Task1]
(
    [ID_Task1] [int] IDENTITY(1,1) NOT NULL,
    [describer] [nvarchar](30) NOT NULL,
    [ID_Entity] [int] NOT NULL,
    [timestamp] [datetime2](7) NOT NULL,
    [individual_task_value] [float] NOT NULL,

    CONSTRAINT [PK_Task1] 
        PRIMARY KEY CLUSTERED ([ID_Task1] ASC)
                    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                          IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                          ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[Task1] 
    ADD CONSTRAINT [DF_Task1_timestamp] DEFAULT (GETDATE()) FOR [timestamp]
GO

ALTER TABLE [dbo].[Task1] WITH CHECK 
    ADD CONSTRAINT [FK_Task1_Entity] 
        FOREIGN KEY([ID_Entity]) REFERENCES [dbo].[Entity] ([id])
GO

ALTER TABLE [dbo].[Task1] CHECK CONSTRAINT [FK_Task1_Entity]
GO

所以基本上一个实体可以有多个不同类型的任务。

创建一个连接所有这些表的查询是否可行,从而为一个实体提供不同的任务(按日期时间排序)?

假设我查询 ID 为 1 的实体并获取分配给它的所有任务的列表:

+-----------+------------------+-------+---------+
| ID_ENTITY |     DATETIME     | TASK  | TASK_ID |
+-----------+------------------+-------+---------+
|         1 | 2020.03.01 17:30 | task1 |       1 |
|         1 | 2020.03.01 17:40 | task2 |       1 |
|         1 | 2020.03.02 06:30 | task1 |       2 |
|         1 | 2020.03.02 06:31 | task3 |       1 |
|         1 | 2020.03.02 06:32 | task2 |       2 |
|         1 | 2020.03.02 08:32 | task2 |       3 |
+-----------+------------------+-------+---------+

(此处的ID_ENTITY 列毫无意义,仅用于演示)

【问题讨论】:

  • 如果您使用Datetime2(7) 数据类型(这是推荐的良好做法),您还应该停止使用GETDATE() 函数(它只返回Datetime,精度为3.33 毫秒)并改用SYSDATETIME()(返回Datetime2(7)

标签: sql sql-server sql-server-2017


【解决方案1】:

在我看来,您对问题的描述类似于 UNION

SELECT ID_Entity,  [timestamp], 'Task1' AS Task, [ID_Task1] AS TaskID
FROM Task1
WHERE ID_Entity = 1

UNION ALL

SELECT ID_Entity,  [timestamp], 'Task2' AS Task, [ID_Task2] AS TaskID
FROM Task2
WHERE ID_Entity = 1

UNION ALL

SELECT ID_Entity,  [timestamp], 'Task3' AS Task, [ID_Task3] AS TaskID
FROM Task3
WHERE ID_Entity = 1

UNION ALL

...

ORDER BY [timestamp];

【讨论】:

  • 谢谢!这正是我想要的!以前从未使用过联合体。
【解决方案2】:

一个简单的UNION ALL 就可以完成这项工作:

select *
from (
  select [ID_Entity], [timestamp], describer, [ID_Task1] as task_id
    from [dbo].[Task1] where [ID_Entity] = 123
  union all 
  select [ID_Entity], [timestamp], describer, [ID_Task2]
    from [dbo].[Task2] where [ID_Entity] = 123
  union all 
  select [ID_Entity], [timestamp], describer, [ID_Task3]
    from [dbo].[Task3] where [ID_Entity] = 123
) x
order by timestamp

【讨论】:

  • 谢谢!这正是我一直在寻找的!以前从未使用过联合体。
【解决方案3】:

你应该为此编写一个递归查询

【讨论】:

    猜你喜欢
    • 2018-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-26
    • 2017-11-26
    • 1970-01-01
    相关资源
    最近更新 更多