1.情景展示
有這樣一種需求:
將數據按照機構進行分組,然后取每個機構下只取一條記錄,如何實現?
2.mysql
分組查詢出來某字段,然后和原來的表進行關聯查詢。
方式一:通過內連接來實現
查看代碼
SELECT
t3.INVOICINGPARTYCODE,
t3.INVOICINGPARTYNAME,
t2.EINVOICECODE,
t2.EINVOICENUMBER,
t2.CARDNO,
t2.PAYERPARTYCODE,
t2.PAYERPARTYNAME
FROM
(
SELECT
ORGID,
max( ID ) ID
FROM
cz_fet_main_mz
WHERE
CARDTYPE = 01
AND LENGTH( CARDNO )= 18
AND KPSTATUS = 1
AND DATE_FORMAT( ISSUETIME, '%Y' )= '2021'
GROUP BY
ORGID
) t,
cz_fet_main_mz t2,
cz_unitinfo t3
WHERE
t2.ORGID = t.ORGID
AND t2.ID = t.ID
AND t3.ORGCODE = t2.ORGID
ORDER BY
t3.CHECKCODE
這里有兩個核心點:
第一,分組查詢出來的字段,需要確保該字段在表中必須具有數據唯一性,不然的話,分組查詢沒有意義;
比方說:時間,但時間也有可能重復,如果我們只精確到秒的話(毫秒也可能會重);
如果表中沒有定義唯一性字段,且確實不知道那個字段具有唯一性,最簡單的方式就是表主鍵(表主鍵本身就具有唯一性)。
第二,將查詢結果當做一張表,來和之前的表建立內連接。
上面的代碼,其實還可以進行簡化:
ORGID字段可以去掉,即:
查看代碼
SELECT
t3.INVOICINGPARTYCODE,
t3.INVOICINGPARTYNAME,
t2.EINVOICECODE,
t2.EINVOICENUMBER,
t2.CARDNO,
t2.PAYERPARTYCODE,
t2.PAYERPARTYNAME
FROM
(
SELECT
max( ID ) ID
FROM
cz_fet_main_mz
WHERE
CARDTYPE = 01
AND LENGTH( CARDNO )= 18
AND KPSTATUS = 1
AND DATE_FORMAT( ISSUETIME, '%Y' )= '2021'
GROUP BY
ORGID
) t,
cz_fet_main_mz t2,
cz_unitinfo t3
WHERE
T2.ID = T.ID
AND t3.ORGCODE = t2.ORGID
ORDER BY
t3.CHECKCODE
執行所需時間:
代碼簡化前耗費時間:
由此可見,SQL不是越簡化越快(另外,重復的where限制條件,加上也並不能提高查詢速度)。
方式二:通過exits來實現
查看代碼
SELECT
t3.INVOICINGPARTYCODE,
t3.INVOICINGPARTYNAME,
t2.EINVOICECODE,
t2.EINVOICENUMBER,
t2.CARDNO,
t2.PAYERPARTYCODE,
t2.PAYERPARTYNAME
FROM
cz_fet_main_mz t2,
cz_unitinfo t3
WHERE
t3.ORGCODE = t2.ORGID
AND EXISTS (
SELECT
1
FROM
cz_fet_main_mz
WHERE
CARDTYPE = 01
AND LENGTH( CARDNO )= 18
AND KPSTATUS = 1
AND DATE_FORMAT( ISSUETIME, '%Y' )= '2021'
GROUP BY
ORGID
HAVING
ORGID = t2.ORGID
AND INVOICENO = t2.INVOICENO
)
ORDER BY
t3.CHECKCODE
使用exists()從邏輯上應該是行得通的,但是,我並沒有測試出來這種方式的真實性。
原因在於:數量太大,查詢結果太慢,用了700多秒還沒執行完,所以,放棄了;
如果你的數據量小的話,可以試試看,如果可行的話,歡迎在評論區留言,我替大家謝謝你。
3.oracle
內連接的語法與mysql一致,這里不再贅述。
4.擴展
關於計數查詢count(1)
count(1)函數,如果表中有索引的話,會自動使用索引字段進行查詢;
如果沒有額外創建索引的話,會自動使用主鍵索引字段進行查詢;(主鍵是唯一索引)
如果對沒有索引的字段進行計數的話,就會全表執行。
沒有使用這種方式的必要,還浪費時間。
關於索引
如上面所示,要進行分組查詢的表,一共有1163萬條數據;
分組和查詢的字段必須得走索引,如果不添加索引的話,那得查到什么時候?(數據少的話,有沒有索引或者走不走索引都無所謂)