0

みなさん、こんにちは
。いくつかの派生テーブルで結合を使用するMySQLクエリがあります。派生クエリの1つはうまく機能し、正しい数の行が返されます。
しかし、各行の関連テーブルからいくつかの追加情報を表示しようとしています。これは私が苦労しているところです。私はここで同様の質問とともに他のいくつかの質問を読みましたが、それを私のクエリに適用することができません。

クエリは次のとおりです。

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`

私の問題は2番目の派生テーブルにあります...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

会社の以前の請求書がない null の場合、請求書フィールドに 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`

したがって、2番目の派生テーブルでは、その特定の行から必要なデータを連結して実行し、その上で MAX() を実行しています。
次に、親クエリで、区切り文字に基づいて部分文字列関数を使用して「爆発」させています。

これは、関係データベース内で頼らなければならない恐ろしい、恐ろしい方法です:(
しかし、機能します:)

于 2011-05-27T22:08:09.113 に答える