0

大家
好,我有一个 MySQL 查询,它在几个派生表上使用连接。其中一个派生查询效果很好,我得到了正确数量的返回行。
但我也试图从相关表中为每一行显示一些额外的信息,这就是我苦苦挣扎的地方。我在这里阅读了其他几个类似问题的问题,但我无法将其应用于我的查询。

这是查询:

SELECT `adbookings`.`company_id`, `companies`.`company_name`, `adbookings`.`run`, `adbookings`.`bill_freq`, `adbookings`.`currency`, FORMAT(`adinserts`.`rate`, 2) AS `rate`, `publications`.`title`, CONCAT(FLOOR(CAST(UNIX_TIMESTAMP()-`invoices`.`last_invoice_stamp` AS SIGNED INTEGER)/86400), ' days ago') AS `last_invoice_days_ago`, `invoices`.`last_invoice_no`, `invoices`.`last_invoice_reference`
FROM `adinserts` 
INNER JOIN 
(
SELECT `publications`.`publication_id`, `publications`.`art_stamp`, `publications`.`title`
FROM `publications`
LEFT JOIN `adinserts` ON `publications`.`publication_id`=`adinserts`.`publication_id` AND `adinserts`.`invoice_id` IS NOT NULL
WHERE `publications`.`publication_stamp`>=UNIX_TIMESTAMP('2010-01-01 00:00:00')
GROUP BY `publications`.`publication_id`
HAVING COUNT(`adinserts`.`invoice_id`)>0
) AS `publications` ON `adinserts`.`publication_id`=`publications`.`publication_id`
LEFT JOIN `adbookings` ON `adinserts`.`booking_id`=`adbookings`.`booking_id` 
LEFT JOIN
(
SELECT `company_id`, CONCAT_WS('', `prefix`, `invoice_id`, `suffix`) AS `last_invoice_no`, MAX(`invoices`.`invoice_stamp`) AS `last_invoice_stamp`, `reference` AS `last_invoice_reference` 
FROM `invoices`
GROUP BY `invoices`.`company_id`
) AS `invoices` ON `adbookings`.`company_id`=`invoices`.`company_id`
LEFT JOIN `companies` ON `adbookings`.`company_id`=`companies`.`company_id` 
WHERE `adinserts`.`invoice_id` IS NULL AND `adinserts`.`cancel_stamp` IS NULL AND `adinserts`.`rate`>0
ORDER BY `publications`.`art_stamp`, `companies`.`company_name`

我的问题是第二个派生表...LEFT JOIN (...) AS invoices

我正在尝试使用 MAX(invoice_stamp) 获取该公司最近相关发票的 invoice_stamp。这似乎有效,并且确实返回了具有最大 invoice_stamp(Unix 时间戳)值的相关记录。

但我也在尝试获取 MAX() 聚合函数返回的该记录的匹配 invoice_id 和参考字段。但是 invoice_id 和 reference 字段与 MAX() 函数返回的记录不匹配。

任何人都知道如何获取派生表中聚合函数返回的记录的完整详细信息?

4

2 回答 2

0

基于 AdInsert 与出版物的 1:1 比率,以及与预订量和最终公司的 1:1 比率,我们不需要反向链接到同一 ID 上的 AdInserts 寻找发票,我们只是忽略。

这些应该是您正在寻找的合格广告插页,并最终需要有关预订/公司的其他信息。通过使用预查询来获取公司的所有初步合格广告插入和最后一张盖章的发票,然后可以通过该发票 ID 和时间戳将其加入发票。

我没有得到您所拥有的“多少天前”,但希望您拥有所需的所有信息,并且一旦您确认此查询完成工作(或大部分工作),就可以重新计算。由于我有一个单一发票的直接链接,而不是将这些字段连接到一个字段中,我只是将它们作为个人保留......再次,您可以根据需要进行调整。

SELECT STRAIGHT_JOIN
      PreQuery.Company_ID,
      PreQuery.Company_Name,
      PreQuery.Run,
      PreQuery.Bill_Freq,
      PreQuery.Currency,
      PreQuery.Rate,
      PreQuery.Publication_ID,
      PreQuery.Booking_ID,
      PreQuery.Art_Stamp,
      PreQuery.Title,
      Invoices.prefix, 
      Invoices.invoice_id, 
      Invoices.suffix,
      Invoices.invoice_stamp,
      Invoices.reference 
   from 
      ( SELECT 
              ab.company_id,
              c.Company_Name
              ab.run,
              ab.bill_freq,
              ab.currency,
              ai.publication_id,
              ai.booking_id,
              format( ai.rate, 2 ) Rate,
              p.title,
              p.art_stamp,
              ( select MAX( invoices.invoice_stamp ) 
                    from Invoices 
                    where Invoices.Company_ID = c.Company_ID ) As LastInvoiceStamp;
           from
              adinserts ai
                 JOIN publications p
                    ON ai.publication_id = p.publication_id
                    and p.publication_stamp >= UNIX_TIMESTAMP('2010-01-01 00:00:00'

                 JOIN adBookings ab
                    ON ai.Booking_ID = ab.Booking_ID

                    JOIN Company c
                       ON ab.Company_id = c.Company_ID

           where
                  ai.Invoice_ID is null
              and ai.Cancel_Stamp is null
              and ai.rate > 0 ) PreQuery

      LEFT JOIN Invoices
         ON PreQuery.Company_ID = Invoices.Company_ID
         AND PreQuery.LastInvoiceStamp = Invoices.Invoice_Stamp

您可能需要将 COALESCE() 应用于发票字段,以防万一在公司没有先前发票的情况下为空,但我认为这与您正在寻找的内容非常接近。

于 2011-05-27T13:13:13.003 回答
0

好的,这是另一种似乎可以返回我想要的方法。虽然不得不求助于这样的事情让我感到身体上的痛苦......

SELECT `adbookings`.`company_id`, `companies`.`company_name`, `adbookings`.`run`, `adbookings`.`bill_freq`, `adbookings`.`currency`, FORMAT(`adinserts`.`rate`, 2) AS `rate`, `publications`.`title`, 
CONCAT(FLOOR(CAST(UNIX_TIMESTAMP()-SUBSTRING_INDEX(`invoices`.`last_invoice`, '-', 1) AS SIGNED INTEGER)/86400), ' days ago') AS `last_invoice_days_ago`, 
SUBSTRING_INDEX( SUBSTRING_INDEX(`invoices`.`last_invoice`, '-', 3), '-', -1) AS `last_invoice_no`, 
SUBSTRING_INDEX( SUBSTRING_INDEX(`invoices`.`last_invoice`, '-', 4), '-', -1) AS `last_invoice_reference` 
FROM `adinserts` 
INNER JOIN 
(
SELECT `publications`.`publication_id`, `publications`.`art_stamp`, `publications`.`title`
FROM `publications`
LEFT JOIN `adinserts` ON `publications`.`publication_id`=`adinserts`.`publication_id` AND `adinserts`.`invoice_id` IS NOT NULL
WHERE `publications`.`publication_stamp`>=UNIX_TIMESTAMP('2010-01-01 00:00:00')
GROUP BY `publications`.`publication_id`
HAVING COUNT(`adinserts`.`invoice_id`)>0
) AS `publications` ON `adinserts`.`publication_id`=`publications`.`publication_id`
LEFT JOIN `adbookings` ON `adinserts`.`booking_id`=`adbookings`.`booking_id` 
LEFT JOIN
(
SELECT `company_id`, MAX(CONCAT_WS('-', `invoice_stamp`, `invoice_id`, CONCAT_WS('', `prefix`, `invoice_id`, `suffix`), `reference`)) AS `last_invoice` 
FROM `invoices`
GROUP BY `invoices`.`company_id`
) AS `invoices` ON `adbookings`.`company_id`=`invoices`.`company_id`
LEFT JOIN `companies` ON `adbookings`.`company_id`=`companies`.`company_id` 
WHERE `adinserts`.`invoice_id` IS NULL AND `adinserts`.`cancel_stamp` IS NULL AND `adinserts`.`rate`>0
ORDER BY `publications`.`art_stamp`, `companies`.`company_name`

因此,在第二个派生表中,我正在运行从该特定行连接我想要的数据,然后在其上运行 MAX()。
然后在父查询中,我使用子字符串函数根据我的分隔符“爆炸”。

这是一个可怕的、可怕的方法,必须在关系数据库中使用:(
但它有效:)

于 2011-05-27T22:08:09.113 回答