2017-05-28 50 views
2

我需要根据所提供的ID列表从表中选择相关的ID - 实际上是一个邻接列表问题。我有一个工作查询单身份证,但它尽管它的工作原理最好坦率地不雅观!我欢迎有关改进的建议以及将单个Id解决方案移至多个Id解决方案的方法。如何选择与多个ID相关的单个行?

我有一个数据库表像这样:

CREATE TABLE [BookingLines] 
(
    [BookingLineId] BIGINT NOT NULL IDENTITY (138, 1), 
    [BookingId] BIGINT NOT NULL, 

    ---- Additional Columns Redacted for brevity 

    [ContractNumber] INT NOT NULL DEFAULT 0, 
    [ContractSubNumber] DECIMAL NOT NULL DEFAULT 0, 

    ---- Additional Columns Redacted for brevity 

); 

在此表中会有记录,并在某些情况下会出现1个或多个对与同一预定ID记录。区分在ContractSubNumber列中,其中一个值为n.0,另一个值为n.1。因此,如果有连续的三双,合同子编号是:

LineId BookingId  SubNumber 
1   1   0.0 
2   1   0.1 
3   1   1.0 
4   1   1.1 
5   1   2.0 
6   1   2.1 

我可能需要从代表任子号的行标识启动,并收集对立之一。所以,如果我从LineId 1开始,我需要检索LineId 2作为相关行。我可以使用多个子选择,这样在单编号做到这一点:

SELECT BookingLineId 
FROM 
(
    SELECT BookingLineId 
    FROM BookingLines 
    WHERE BookingId = 1 
    AND FLOOR(ContractSubNumber) = 
    (
     SELECT FLOOR(ContractSubNumber) 
     FROM BookingLines 
     WHERE BookingId = 1 AND BookingLineId = (1) 
    ) 
) 
WHERE BookingLineId <> 1; 

这正常工作,在这种情况下返回值2。

  1. 我该如何使这更优雅高效?
  2. 我该如何重写这个函数以返回指定列表中所有Ids的相对值

    WHERE BookingId = 1 AND BookingLineId IN(1,3,5))

,并将它返回结果2,4,6-?

所有建议感激地收到。

编辑

我已经改正在原来的问题提供的SQL错字,并使用由@McNets提出的框架,这是我去了解决方案:

SELECT BL.BookingLineId 
FROM BookingLines BL 
INNER JOIN BookingLines ABL ON ABL.BookingId = BL.BookingId 
AND ABL.BookingLineId IN (22, 24, 26) 
AND FLOOR(BL.ContractSubNumber) = FLOOR(ABL.ContractSubNumber) 
WHERE BL.BookingId = 3 AND BL.BookingLineId NOT IN (22,24,26); 

我非常感谢贡献和最终答案。多谢你们!

+0

你可以[最小的例子](https://stackoverflow.com/help/mcve)? – McNets

+0

@McNets - 对不起,这是一个错字。该表是相同的,即AgencyBookingLines应阅读BookingLines – oldcoder

回答

0

至于没有关于AgencyBookingLines的信息,我不能建立一个fiddle例如没有样本数据,但我认为你可以将AgencyBookingLines子查询移动到ON子句。

SELECT  BL.BookingLineId 
FROM  BookingLines BL 
INNER JOIN AgencyBookingLines ABL 
ON   ABL.BookingId = BL.BookinId 
AND  ABL.BookingLineId = 1 
AND  FLOOR(BL.ContractSubNumber) = FLOOR(ABL.ContractSubNumber 
WHERE  BL.BookingId = 1 
AND  BL.BookingLineId <> 1; 
-- 
-- AND  BL.BookingLineId IN (2,4,6); 
+0

嗨@McNets, 感谢您的帮助与这一个。更正大小写和表名,并使用自连接给我我想要的。这是自我加入,我无法摆脱困境。再次抱歉,这是一个令人困惑的错字... – oldcoder

+0

我很乐意提供帮助。 – McNets

0

它的子编号总是* .0 & * .1。然后,你可以试试下面的

SELECT oppo.* 
FROM AgencyBookingLines AS main 
INNER JOIN AgencyBookingLines AS oppo ON 
oppo.BookingId = main.BookingId 
AND oppo.SubNumber <> main.SubNumber 
AND FLOOR(oppo.SubNumber) = FLOOR(main.SubNumber) 
WHERE main.BookingId = 1 
     AND main.LineId IN (1,3,5)