从中间表中获取记录,或者如果不存在则获取所有记录

时间:2019-07-09 13:20:43

标签: sql sql-server database

我有以下数据库架构:

CREATE TABLE [dbo].[TableType]
    (
    [id]       INT NOT NULL, 
    [name]     VARCHAR(100) NOT NULL,
    CONSTRAINT [PK_TableType] PRIMARY KEY CLUSTERED ([id] ASC), 
)
CREATE TABLE [dbo].[ColumnType]
    (
    [id]       INT NOT NULL, 
    [name]     VARCHAR(100) NOT NULL,
    CONSTRAINT [PK_ColumnType] PRIMARY KEY CLUSTERED ([id] ASC), 
)
CREATE TABLE [dbo].[TableTypeAllowedObjectType]
    (
    [id]                    INT IDENTITY (1, 1) NOT NULL, 
    [id_table_type]         INT NOT NULL,
    [id_column_type]        INT NOT NULL,
    [default_value]         BIT NOT NULL,
    CONSTRAINT [PK_TableTypeAllowedObjectType] PRIMARY KEY CLUSTERED ([id] ASC), 
    CONSTRAINT [FK_TableTypeAllowedColumnType_ColumnType] FOREIGN KEY ([id_column_type]) REFERENCES [dbo].[ColumnType]([id]),
    CONSTRAINT [FK_TableTypeAllowedColumnType_TableType] FOREIGN KEY ([id_table_type]) REFERENCES [dbo].[TableType]([id]),
)

数据样本:

DELETE FROM dbo.TableTypeAllowedObjectType;
DELETE FROM dbo.TableType;
DELETE FROM dbo.ColumnType;

INSERT INTO dbo.TableType (id, name) values (1, 'TableType1');
INSERT INTO dbo.TableType (id, name) values (2, 'TableType2');

INSERT INTO dbo.ColumnType (id, name) values (1, 'ColumnType1');
INSERT INTO dbo.ColumnType (id, name) values (2, 'ColumnType2');
INSERT INTO dbo.ColumnType (id, name) values (3, 'ColumnType3');

INSERT INTO dbo.TableTypeAllowedObjectType (id_table_type, id_column_type, default_value) values(1, 1, 0);
INSERT INTO dbo.TableTypeAllowedObjectType (id_table_type, id_column_type, default_value) values(1, 2, 0);

如果ColumnType中有任何记录,我需要获取id_table_type的所有[dbo].[TableTypeAllowedObjectType]条记录。如果没有特定id_table_type的记录,则查询应返回所有ColumnType记录。

TableType1的假定查询应如下所示

SELECT * FROM dbo.ColumnType ... WHERE id_table_type = 1

并返回ColumnType记录:

1   ColumnType1
2   ColumnType2

针对TableType2的查询应返回所有记录:

1   ColumnType1
2   ColumnType2
3   ColumnType3

在此特定示例中,我需要获取TableType2的所有ColumnType记录以及TableType1的ColumnTypes 1和2。

SQLFiddle link

任何想法如何以或多或少有效的方式实现这一目标?

谢谢。

1 个答案:

答案 0 :(得分:1)

这是我能够在SSMS中工作的示例:

-- Sample tables.
DECLARE @TableType TABLE ( [id] INT NOT NULL, [name] VARCHAR(100) NOT NULL );
DECLARE @ColumnType TABLE ( [id] INT NOT NULL, [name] VARCHAR(100) NOT NULL );
DECLARE @TableTypeAllowedObjectType TABLE (
    [id] INT IDENTITY (1, 1) NOT NULL, [id_table_type] INT NOT NULL, [id_column_type] INT NOT NULL, [default_value] BIT NOT NULL
);

-- Sample data.
INSERT INTO @TableType (id, [name]) VALUES (1, 'TableType1'), (2, 'TableType2');
INSERT INTO @ColumnType (id, [name]) VALUES (1, 'ColumnType1'), (2, 'ColumnType2'), (3, 'ColumnType3');
INSERT INTO @TableTypeAllowedObjectType (id_table_type, id_column_type, default_value) VALUES (1, 1, 0), (1, 2, 0);

-- Variable for table type id.
DECLARE @TableTypeID INT = 1;

-- Query data based on table type id.
IF EXISTS( SELECT * FROM @TableTypeAllowedObjectType WHERE id_table_type = @TableTypeID )
    SELECT * FROM @ColumnType AS ColumnType
    WHERE EXISTS (
        SELECT * FROM @TableTypeAllowedObjectType AS AllowedType
        WHERE 
            ColumnType.id = AllowedType.id_column_type
            AND AllowedType.id_table_type = @TableTypeID
    )
ELSE
    SELECT * FROM @ColumnType AS ColumnType
    WHERE NOT EXISTS (
        SELECT * FROM @TableTypeAllowedObjectType AS AllowedType
        WHERE 
            ColumnType.id = AllowedType.id_column_type
            AND AllowedType.id_table_type = @TableTypeID
    )

@TableTypeID = 1返回:

+----+-------------+
| id |    name     |
+----+-------------+
|  1 | ColumnType1 |
|  2 | ColumnType2 |
+----+-------------+

@TableTypeID = 2返回:

+----+-------------+
| id |    name     |
+----+-------------+
|  1 | ColumnType1 |
|  2 | ColumnType2 |
|  3 | ColumnType3 |
+----+-------------+

我相信这就是您想要的吗?

更新:向TVF添加功能。

您可以将此功能添加到表值函数中,该函数应该可以从您的视图中调用。这是一个基于此处可用信息的示例:

-- Create TVF.
CREATE FUNCTION dbo.GetTableTypeColumns (
    @TableTypeID INT
)
RETURNS @Results TABLE (
    id INT, [name] VARCHAR(50)
)
AS
BEGIN


    IF EXISTS( SELECT * FROM dbo.TableTypeAllowedObjectType WHERE id_table_type = @TableTypeID ) BEGIN

        INSERT INTO @Results ( id, [name] )
        SELECT * FROM dbo.ColumnType
        WHERE EXISTS (
            SELECT * FROM dbo.TableTypeAllowedObjectType AS AllowedType
            WHERE 
                ColumnType.id = AllowedType.id_column_type
                AND AllowedType.id_table_type = @TableTypeID
        )

    END ELSE BEGIN

        INSERT INTO @Results ( id, [name] )
        SELECT * FROM dbo.ColumnType
        WHERE NOT EXISTS (
            SELECT * FROM dbo.TableTypeAllowedObjectType AS AllowedType
            WHERE 
                ColumnType.id = AllowedType.id_column_type
                AND AllowedType.id_table_type = @TableTypeID
        )

    END

    RETURN

END
GO

创建TVF之后,您可以像这样调用它:

SELECT * FROM dbo.GetTableTypeColumns( 1 );

返回

+----+-------------+
| id |    name     |
+----+-------------+
|  1 | ColumnType1 |
|  2 | ColumnType2 |
+----+-------------+

SELECT * FROM dbo.GetTableTypeColumns( 2 );

返回

+----+-------------+
| id |    name     |
+----+-------------+
|  1 | ColumnType1 |
|  2 | ColumnType2 |
|  3 | ColumnType3 |
+----+-------------+