多條SQL語句對查詢結果集的垂直合並,以及表設計時如何冗余字段


需求引入

你有一個銷售單表A 和一個銷售單詳情表B 和一個收付款記錄表C 

A---->B 一對多   A---->C一對多

如果一個銷售單有兩個詳情,三條收款記錄

對一個銷售單 我們想查詢出一個結果集 有銷售單的id、詳情總額、銷售單的收款總額

如果你select A  join B on(B和A的外鍵) 查詢出2條記錄結果集

如果你select A  join C on(C和A的外鍵) 查詢出3條記錄結果集

那你 如果你select A  join B on(B和A的外鍵)  join C on(C和A的外鍵) 查詢出2*3=6條記錄結果集 然后在sum

如果select語句中有聚合函數(sum count )很可能導致查詢的結果不符合需求的要求。因為詳情總額只需要對兩條記錄進行sum  收款進行需要三條 而sum之前我們查出來了六條

解決辦法

1. 用兩條sql查詢 然后通過java對結果集進行合並。

缺點:只能對一些簡單的需求,如果多個銷售單,還要做分頁 而且有 付款記錄和詳情的搜索條件 JAVA很難做

2. 用兩條sql查詢  然后就是用sql的垂直合並了

select * from (sql1)  join (sql2) on(sql1.銷售單的主鍵=sql2.銷售單的主鍵) 就是把兩條sql當成兩個子查詢

優點:解決了用java操作List進行合並,做不了分頁搜索的問題。因為我們用的一個SQL 無論需求怎么搜索分頁,都可以搞定

工作中做某張報表的時候發現的。sql語句含有多個一對多關系的時候 注意影響聚合函數的結果。所以采用了先拆分sql,然后根據需求垂直合並。

設計表結構的時,如何避免出現過長的SQL查詢

冗余一些字段,比如你需要對收付款記錄的某一個字段(比如金額)做sum 把這個字段冗余到一張額外的表里面。

方法一:每次進行收付款的時候加減這個字段。這樣做報表的時候就不必再關聯收付款記錄表做關聯求sum了(這樣的話 有哪個接口忘記更新收付款就完蛋了 很難排查)

方法二 :每次進行收付款的時候 從新進行一遍收付款的sum放進銷售單里面,比較消耗性能。引入消息隊列 異步的操作這種接口。

方法三  :收付款的時候多開一個線程,去更新sum字段

當我們把計算邏輯(比如錢的增量)寫在SQL里面的時候 可以不用樂觀鎖,因為SQL會讀到其他已經提交的事物,但是如果這個錢是先計算好,然后直接update的 需要用樂觀鎖


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM