mysql、oracle 分組查詢,每組取一條數據


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萬條數據;

分組和查詢的字段必須得走索引,如果不添加索引的話,那得查到什么時候?(數據少的話,有沒有索引或者走不走索引都無所謂)

寫在最后

  哪位大佬如若發現文章存在紕漏之處或需要補充更多內容,歡迎留言!!!

 相關推薦:


免責聲明!

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



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