2013-07-23 82 views
0

我在SQL Server 2008中運行查詢..我有一個sales表和一個payments表..有時銷售有多種付款方式(部分禮品卡+零件現金或零件信用+部分現金等)。所以我想要做的是在表格中列出每筆銷售的銷售額和付款。SQL查詢一對多關係連接無重複

如果我做了我LEFT JOIN ON sales.SaleID = payments.SaleID得到重複銷售行時有多個匹配的支付行..

所以,我一直在做的是讓所有的銷售和多少匹配的付款行的總數有與(SELECT COUNT(*) FROM payments WHERE payments.SaleID = sales.SaleID) AS NumOfPayments。然後在我的PHP腳本中查看付款數量,如果是> 1,我然後運行另一個查詢來獲取付款詳細信息。

我試圖讓會是這個樣子

----------------------------------------------------- 
| SaleID | SaleDate | Amount | Payments   | 
----------------------------------------------------- 
| 123 | 2013-07-23 | $ 19.99 | Cash:  $ 19.99 | 
| 124 | 2013-07-23 | $ 7.53 | Cash:  $ 7.53 | 
| 125 | 2013-07-23 | $174.30 | Credit: $124.30 | 
|  |   |   | GiftCard: $ 50.00 | 
| 126 | 2013-07-23 | $ 79.99 | Cash:  $ 79.99 | 
| 127 | 2013-07-23 | $100.00 | Credit: $ 90.00 | 
|  |   |   | Cash:  $ 10.00 | 
----------------------------------------------------- 

凡售賣125和127列出了多個付款,但銷售信息僅供出現一次,不重複,每次付款的輸出。

salespayments表如下所示:

Sales        Payments 
--------------------------------- -------------------------------------------- 
| SaleID | SaleDate | Amount | | PaymentID | SaleID | PmtMethod | PmtAmt | 
--------------------------------- -------------------------------------------- 
| 123 | 2013-07-23 | $ 19.99 | |  158 | 123 |  4 | $ 19.99 | 
| 124 | 2013-07-23 | $ 7.53 | |  159 | 124 |  4 | $ 7.53 | 
| 125 | 2013-07-23 | $174.30 | |  160 | 125 |  2 | $124.30 | 
| 126 | 2013-07-23 | $ 79.99 | |  161 | 125 |  3 | $ 50.00 | 
| 127 | 2013-07-23 | $100.00 | |  162 | 126 |  4 | $ 79.99 | 
--------------------------------- |  163 | 127 |  2 | $ 90.00 | 
            |  164 | 127 |  4 | $ 10.00 | 
            -------------------------------------------- 

我覺得如果我可以做只是SQL它會更快。有沒有一種方法可以用純SQL來實現,而不必使用服務器端代碼來運行條件查詢。

+0

所有銷售額在支付表中至少有一個記錄,對嗎? – Vasanth

+0

@VasanthSundaralingam是的每個銷售至少應該有一個相應的付款記錄 –

回答

1

我不會混合數據檢索和數據顯示,這是我想你問的。您是否有某種欄目來指示首先應該顯示哪些付款?我想是這樣的:

SELECT columnlist, 
rn = ROW_NUMBER() OVER (PARTITION BY sales.salesID ORDER BY payment.paymentID) 
FROM sales JOIN payments ON sales.salesID=payments.salesID 

然後,在你的GUI,只顯示值第3列,其中RN = 1,並空出的值,其中RN> 1

+0

我已經使用mysql 5.6這種方法,它給了我驚人的具體信息「你有一個SQL語法錯誤」:( – danba

+0

MySQL不是SQL服務器:)我不認爲MySQL支持ROW_NUMBER()功能。 –

0

這是可能更容易在界面中做到這一點。

你想要的基本的查詢是:

select s.saleID, s.SaleDate, s.Amount, 
     p.PaymentType, p.PaymentAmount, 
     ROW_NUMBER() over (partition by p.SaleId order by p.PaymentAmount desc) as seqnum 
    from sales s join 
     payments p 
     on p.saleID = s.saleId 
    order by 1, 2 

但是,你想空出的字段。要做到這一點,你需要的所有字段轉換爲字符串,然後檢查其是對每個SaleId的第一行:

select (case when seqnum > 1 then '' else CAST(SaleId as varchar(255)) end) as SaleId, 
     (case when seqnum > 1 then '' else CONVERT(varchar(10), SaleDate, 121) end) as SaleDate, 
     (case when seqnum > 1 then '' else '$'+STR(amount, 6, 2) end) as Amount, 
     PaymentType, PaymentAmount 
from (select s.saleID, s.SaleDate, s.Amount, 
      p.PaymentType, p.PaymentAmount, 
      ROW_NUMBER() over (partition by p.SaleId order by p.PaymentAmount desc) as seqnum 
     from sales s join 
      payments p 
      on p.saleID = s.saleId 
    ) sp 
order by SaleId, SaleDate; 

這不是SQL是專爲操作的類型。 SQL適用於所有列具有相同含義的表。在這裏,您根據其在銷售中的位置介紹了專欄的不同含義。是的,SQL可以做到這一點。不,這不容易。

0

以下查詢會給出您需要的結果,您需要跳過SalesIDToSort列。

;with SalesData 
    as 
    (
    select 
     Sales.SalesID, Sales.SalesDate, Sales.TotalAmount, Payments.PaymentMode, Payments.Amount, 
     Row_Number() over(Partition by Sales.SalesID order by Payments.PaymentID) RowNum 
    from 
     Payments 
     inner join Sales on Payments.SalesID = Sales.SalesID 
) 
    select SalesID, SalesDate, TotalAmount, PaymentMode, Amount, SalesID SalesIDToSort 
    from 
    SalesData 
    where 
    SalesData.RowNum = 1 
    union all 
    select null, null, null, PaymentMode, Amount, SalesID SalesIDToSort 
    from 
    SalesData 
    where 
    SalesData.RowNum > 1 
    order by 6 

Working demo

0

您可以嘗試通過功能gourp等業態於:

select salesid, salesDate, Amount, FORMAT(payment, 9999.999) as payments 
from FROM payments 
WHERE payments.SaleID = sales.SaleID 
group by salesid; 

,如果您有格式作爲可用的功能,這可能工作。