2

所以情况是我有一个涉及 9 个表的查询,我需要编写它以便它返回所有记录,即使表中impactid是.workorderstatesNULL

在下面的查询之前,我注意到我没有得到所有“打开”的结果,因为最初我只是在表中的位置和情况workorderstates.impactid = impactdefiniton.impactid下这个条件不成立,因此消除了应该返回的记录,因为它们实际上是“开放的”。impactidNULLworkorderstates

所以我在下面设计了这个查询,但每次运行它都不起作用。它将返回不唯一的表别名workorder。如果我对表使用别名,它只会在连接中的正确表上移动,因为它不是唯一的。任何人都可以在重组查询方面为我提供任何帮助以使其正常工作吗?我已经尝试了很多变体,有趣的是,第二个查询几乎可以工作,但它返回重复的记录(在这种情况下是四个相同的记录)

select workorder.workorderid, workorder.siteid, 
 FROM_UNIXTIME(workorder.CREATEDTIME/1000, '%m-%d-%Y %H:%i:%s') as createdate, 
 categoryname, IFNULL(workorderstates.impactid, "No Set") as impactid, 
 IFNULL(impactdefinition.name, "Not Set") as impactname, first_name,
 sdorganization.name, statusname, title 
from workorder,  statusdefinition, sitedefinition, sdorganization, 
 prioritydefinition, categorydefinition, sduser, aaauser, workorderstates 
left Join impactdefinition on workorderstates.impactid = impactdefinition.impactid  
left join workorder on workorder.workorderid = workorderstates.workorderid 
left join workorderstates on workorderstates.statusid = statusdefinition.statusid 
left join workorder on workorder.siteid = sitedefinition.siteid 
left join sitedefinition on sitedefinition.siteid = sdorganization.org_id  
left join workorderstates on workorderstates.categoryid = categorydefinition.categoryid
left join workorder on workorder.requesterid = sduser.userid 
left join sduser on sduser.userid = aaauser.user_id  
where statusname='Open' and workorder.createdtime >= '1352678400000' 
 and sdorganization.name='MAPL' 
order by workorder.workorderid

几乎可以工作但很难看的查询(返回重复的记录):

select workorder.workorderid, workorder.siteid, 
 FROM_UNIXTIME(workorder.CREATEDTIME/1000, '%m-%d-%Y %H:%i:%s') as createdate,  
 categoryname, IFNULL(workorderstates.impactid, "No Set") as impactid, 
 IFNULL(impactdefinition.name, "Not Set") as impactname, first_name, 
 sdorganization.name, statusname, title 
from workorder,  statusdefinition, sitedefinition, sdorganization, 
 prioritydefinition, categorydefinition, sduser, aaauser, workorderstates 
left Join impactdefinition on workorderstates.impactid = impactdefinition.impactid 
where workorder.workorderid = workorderstates.workorderid 
 and workorderstates.statusid = statusdefinition.statusid 
 and workorder.siteid = sitedefinition.siteid 
 and sitedefinition.siteid = sdorganization.org_id 
 and workorderstates.categoryid = categorydefinition.categoryid 
 and  workorder.requesterid = sduser.userid and sduser.userid = aaauser.user_id 
 and statusname='Open' and workorder.createdtime >= '1352678400000' 
and sdorganization.name='MAPL' 
order by workorder.workorderid

关于如何让这个查询工作的任何想法???多谢你们!

4

2 回答 2

1

我查看了您的查询,我认为您对 JOIN 以及如何编写它们有一些基本的误解。这就像你只是在随机猜测语法,这不是编写代码的方式。

我检查了您的查询并将其转换为 SQL-92 语法。我不得不对连接条件做出一些推论,所以我不能保证它对您的应用程序是正确的,但它更接近于合法查询。

只有我在您的示例中找不到加入您prioritydefinition表的任何条件。这可能是您重复行的原因。您正在生成所谓的笛卡尔积

select workorder.workorderid, workorder.siteid, 
 FROM_UNIXTIME(workorder.CREATEDTIME/1000, '%m-%d-%Y %H:%i:%s') as createdate, 
 categoryname, IFNULL(workorderstates.impactid, "No Set") as impactid, 
 IFNULL(impactdefinition.name, "Not Set") as impactname, first_name,
 sdorganization.name, statusname, title 
from workorder
inner join statusdefinition on workorderstates.statusid = statusdefinition.statusid
inner join sitedefinition on workorder.siteid = sitedefinition.siteid
inner join sdorganization on sitedefinition.siteid = sdorganization.org_id
inner join prioritydefinition ...NO JOIN CONDITION FOUND...
inner join categorydefinition on workorderstates.categoryid = categorydefinition.categoryid
inner join sduser on workorder.requesterid = sduser.userid
inner join aaauser on sduser.userid = aaauser.user_id
inner join workorderstates on workorder.workorderid = workorderstates.workorderid
left Join impactdefinition on workorderstates.impactid = impactdefinition.impactid  
where statusname='Open' 
 and workorder.createdtime >= '1352678400000' 
 and sdorganization.name='MAPL' 
order by workorder.workorderid

在编写更多 SQL 连接之前,您确实需要找一个了解您的应用程序并且知道如何编写 SQL 的人来指导您。

于 2013-02-17T17:36:22.320 回答
0

我也重新格式化了您的查询,但它在视觉上更具层次性,以显示从第一个(左侧)表到它从(右侧)表中获取详细信息的关系。正如比尔所提到的,你有一个额外的桌子没有做任何事情,因此你的笛卡尔积。

现在,如果您陷入困境并且没有其他人可以真正帮助,这里是 LEFT-JOIN 与 INNER-JOIN 的基本知识。左连接基本上说我想要左侧表中的每条记录(如我首先列出的那样),无论右侧是否有记录。如果有匹配,很好,没问题......但如果没有匹配,您的查询仍然会运行。

所以,我已经设置为所有 LEFT-JOIN。您可以根据需要更改那些您知道必须始终存在的人......例如“用户”输入工作订单。这样你就可以改变。希望这可以帮助你。另请查看我如何从工作订单状态嵌套到工作订单状态以及从工作订单状态中嵌套以获取相应的状态定义以及与工作订单状态表相关联的其他内容。其他的则与工单直接相关,因此属于那个等级。

最后一点...并非所有字段都是 table.field 引用(我将其更改为别名以提高可读性)。使您的所有字段合格,以便您和其他试图帮助或将来阅读您的代码的人知道该字段的来源,而不仅仅是猜测(它在其中一个表中)

select 
      WO.workorderid, 
      WO.siteid, 
      FROM_UNIXTIME(WO.CREATEDTIME/1000, '%m-%d-%Y %H:%i:%s') as createdate,  
      categoryname, 
      IFNULL(WOS.impactid, "No Set") as impactid, 
      IFNULL(ImpD.name, "Not Set") as impactname, first_name, 
      SDO.name, 
      statusname, 
      title 
   from 
      workorder WO
         LEFT JOIN workorderstates WOS
            ON WO.workorderid = WOS.workorderid 

            LEFT JOIN statusdefinition StatD
               ON WOS.statusid = StatD.statusid 

            LEFT JOIN categorydefinition CatD
               ON WOS.categoryid = CatD.categoryid 

            LEFT JOIN impactdefinition ImpD
               ON WOS.impactid = ImpD.impactid 

         LEFT JOIN sitedefinition SiteD
            ON WO.siteid = SiteD.siteid 

            LEFT JOIN sdorganization SDO
               ON SiteD.siteid = SDO.org_id 
              and SDO.name = 'MAPL' 

         LEFT JOIN sduser U
            ON WO.requesterid = U.userid 

            LEFT JOIN aaauser AU
               ON U.userid = AU.user_id

   where 
          statusname = 'Open' 
      and WO.createdtime >= '1352678400000' 
   order by 
      WO.workorderid
于 2013-02-17T17:56:30.197 回答