【问题标题】:create view for items not in list为不在列表中的项目创建视图
【发布时间】:2012-01-31 20:29:47
【问题描述】:

我有两张桌子。表 1 是带有equipment_idequipment_description 的设备主列表。所以,假设这张桌子我有十个equipment_id。 1,2,3....10 个,每个都附有一些描述。

设备检查后的表2日志:

equipment_id|inspection_date
       1    |    '1-22-2012'
       2    |    '1-22-2012'
       4    |    '1-22-2012'
       2    |    '1-23-2012'
       3    |    '1-23-2012'

我创建了一个视图v_dates,它从表 2 中提取了所有不同的检查日期 - 不确定我是否需要它,但还是做了。

我想创建另一个视图,显示 v_dates 中每个日期未检查的所有设备。所以它会显示:

3 | '1-22-2012'
5 | '1-22-2012'

等等。

这里是新手,只是不确定如何正确加入这些表格。无法让它工作,希望能提供任何帮助。

【问题讨论】:

  • 您使用的是什么 SQL 服务器软件?
  • 在没有检查的那一天,你想看所有的条目吗?如果是这样,那么使用列出所有可能检查日期的参考表会更容易。
  • 这种性质的问题很尴尬,因为您有两个关系,并且您有点要求两个集都缺少信息的结果。 @MikeRyan 是对的 - 应该进行检查的日期参考表可以更容易解决。

标签: sql views


【解决方案1】:

未经测试,但我认为这应该会产生预期的结果:

SELECT i.id,d.date FROM 
    ( SELECT DISTINCT inspection_date AS date FROM inspections ORDER BY 1 ) d 
  LEFT JOIN 
    inspections i 
  ON d.date=i.date
WHERE i.date IS NULL
GROUP BY 1,2
ORDER BY 1,2

就像 cmets 中提到的那样,带有检查日期的表格真的很有帮助。

【讨论】:

  • DGW 也感谢您的帮助。我会看看我得到什么结果。
  • 这并没有显示equipment_id。另外 - GROUP BYORDER BY 序号位置既幸运又危险。
【解决方案2】:

根据我使用 SQL SERVER 2005 的测试数据,以下内容似乎有效。我正在使用不同日期的 CROSS JOIN 以及 LEFT JOIN 来丢弃这些日期存在的 EQUIPMENT_ID 记录。

抱歉,我在使用制表符和空格正确设置代码格式时遇到问题...

IF OBJECT_ID('tempdb..#EQUIPMENT') IS NOT NULL
    DROP TABLE #EQUIPMENT

CREATE TABLE #EQUIPMENT
    (   EQUIPMENT_ID        smallint,
        EQUIPMENT_DESC  varchar(32)
    )

INSERT INTO #EQUIPMENT
    (   EQUIPMENT_ID,   EQUIPMENT_DESC  )
            SELECT  1,  'AAA'
UNION   SELECT  2,  'BBB'
UNION   SELECT  3,  'CCC'
UNION   SELECT  4,  'DDD'
UNION   SELECT  5,  'EEE'
UNION   SELECT  6,  'FFF'
UNION   SELECT  7,  'GGG'
UNION   SELECT  8,  'HHH'
UNION   SELECT  9,  'III'
UNION   SELECT  10, 'JJJ'

IF OBJECT_ID('tempdb..#INSPECTION') IS NOT NULL
    DROP TABLE #INSPECTION

CREATE TABLE #INSPECTION
    (   EQUIPMENT_ID        smallint,
        INSPECTION_DATE smalldatetime
    )

INSERT INTO #INSPECTION
    (   EQUIPMENT_ID, INSPECTION_DATE   )
            SELECT  1, '1-22-2012'
UNION SELECT    1, '1-27-2012'
UNION SELECT    3, '1-27-2012'
UNION SELECT    5, '1-29-2012'
UNION SELECT    7, '1-22-2012'
UNION SELECT    7, '1-27-2012'
UNION SELECT    7, '1-29-2012'

SELECT  E.EQUIPMENT_ID, D.INSPECTION_DATE
FROM        #EQUIPMENT          E
CROSS   JOIN    (   SELECT  DISTINCT INSPECTION_DATE
                            FROM        #INSPECTION
                        )   D
LEFT JOIN   #INSPECTION     I2
    ON      E.EQUIPMENT_ID = I2.EQUIPMENT_ID
    AND     D.INSPECTION_DATE = I2.INSPECTION_DATE
WHERE   I2.EQUIPMENT_ID IS NULL
ORDER BY E.EQUIPMENT_ID, D.INSPECTION_DATE

【讨论】:

    【解决方案3】:

    根据我对该问题的评论,您确实需要一张有效检查日期表。它使 sql 更加明智,此外,如果您想查看列出的所有项目的日期,当检查应该进行但没有进行检查时,这是唯一的方法。

    所以,假设有两张表:

     create table inspections (equipment_id int, inspection_date date);
    
     create table inspection_dates (id int, inspection_date date);
    

    然后,在应进行检查的日期获取所有未进行检查的设备的联接将是:

     select i.equipment_id, id.inspection_date
     from inspection_dates id, 
        (select distinct equipment_id from inspections) i
     where not exists (select * from inspections i2
                           where i2.inspection_date = id.inspection_date
                                and i2.equipment_id = i.equipment_id);
    

    您想要不存在的组合。因此不存在谓词。

    再次注意,您可能会有一个包含所有唯一设备 ID 的表,但不知道我必须自己构建它。

    【讨论】:

    • 谢谢迈克。检查应该是一年中的每一天,但可能会有几天不进行检查。我的报告显示了他们所做的检查,但我认为显示哪些检查也被遗漏了可能会有所帮助。在 mysql 中尝试此操作,但在我完成 oracle 后将运行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-26
    • 2018-01-08
    • 2017-06-24
    • 2017-10-27
    • 2011-03-23
    • 2018-02-17
    相关资源
    最近更新 更多