數據處理---那些年遇到的SQL彙總

     那些年遇到的SQL問題真的不少,各種類型的,有面試的時候遇到的SQL,有開發的時候遇到的,有性能優化的時候遇到的,還有在網上看到的各種資料的,林林總總,問題不少,這裏做個彙總,從以下幾個方面說下:1,各種SQL語句;2索引和SQL性能Explain;3 JOIN相關,爲了忘卻的的紀念:

1,各種常見SQL語句

  • 各種Join:內聯接,外聯接(LEFT OUTER JOIN,RIGHT  OUTER  JOIN,FULL OUTER JOIN),交叉聯接(笛卡爾積)

 

SELECT a.*,b.*  FROM bbb b,aaa a;SELECT a.*,b.*  FROM aaa a CROSS JOIN  bbb b;
SELECT * FROM aaa a NATURAL INNER JOIN bbb b;
     A,B兩個表列名完全不同,上面的結果是相同的。注意第三個NATURAL INNER JOIN如果列名有相同,結果大不相同。
    有這麼一個題目:一個叫 team 的表,裏面只有一個字段name, 一共有4 條紀錄,分別是a,b,c,d, 對應四個球隊,現在四個球隊進行比賽,用一條sql 語句顯示所有可能的比賽組合。
    答:select a.name, b.name from team a, team b where a.name < b.name

 

  • 行列轉換

SELECT a.name,SUM(CASE WHEN a.subject='語文' THEN a.score ELSE 0 END) AS 語文,SUM(CASE WHEN a.subject='數學' THEN a.score ELSE 0 END) AS 數學,SUM(CASE WHEN a.subject='英語' THEN a.score ELSE 0 END) AS 英語from  a_student a GROUP BY a.name;
SELECT NAME, (select score from a_student m where m.subject='語文' and m.name=a.name) as 語文,(select score from a_student m where m.subject='數學' and m.name=a.name) as 數學,(select score from a_student m where m.subject='英語' and m.name=a.name) as 英語from a_student a  group by NAME;
    這個例子不多說了,關鍵是要明白group 之後是個什麼樣的結果,再來做些處理,順便看下case語句的寫法。可能還有其他的寫法,另外有pivot table的用法。

  • 刪除重複數據

 

      很明顯,第5條記錄和第一條重複了,刪除表中多餘的重複記錄(多個字段,例如name和subject),只留有rowid最小的記錄:
delete from a_student a where (a.name,a.subject) in (select NAME,subject from a_student group by NAME,subject having count(*) > 1) and rowid not in (select min(rowid) from a_student group by NAME,subject having count(*)>1)

 

  • 樹形結構數據查詢

  樹形結構的一般是用with 做個臨時表,然後父數據和子數據做個內連接,把臨時表查詢出來;

 

  當然寫存儲過程也可以實現,或者用oracle 的start with condition   connect by prior的語句也可以;

 

2,索引和SQL性能Explain

  造了兩張表,表結構完全相同TEST_A100和TEST_A1000,只是數據量不同,前者塞入100萬數據,後者1000萬,後面的區域表大約1萬條記錄
create table TEST_A1000 (
  ID       number not null,
  NAME     varchar2(32),
  CITY     number,
  PROVINCE number,
  DOB      date
);

 

建立區域表和序列:

 

 create table TEST_AREA (
  ID       number not null,
  NAME     varchar2(32),
  PROV_ID  number not null,
  detail   varchar2(2000)
);
create sequence SEQ_TESTAREA
minvalue 1
maxvalue 999999999
start with 1
increment by 1
cache 1000;

 

create or replace procedure PROC_ISTAS
begin
  for i in 1..10000000 LOOP
    insert into TEST_A1000 SELECT SEQ_TESTA.Nextval,DBMS_RANDOM.STRING('A', 32),TRUNC(DBMS_RANDOM.VALUE(100, 1100)),TRUNC(DBMS_RANDOM.VALUE(0, 100)),to_date(2451984+TRUNC(DBMS_RANDOM.VALUE(0,365)),'J') from dual ;
    IF MOD(i,10000)=0 THEN
      --dbms_output.put_line('執行開始,時間: ' || sysdate); 
      commit;
    END IF;
  end loop;
end;
begin
  PROC_IST;
end;
也可以這樣塞入數據(使用隨借函數和connect by):
insert into TEST_A100 SELECT SEQ_TESTA.Nextval,DBMS_RANDOM.STRING('A', 32),TRUNC(DBMS_RANDOM.VALUE(100, 1100)),TRUNC(DBMS_RANDOM.VALUE(0, 100)),to_date(2451984+TRUNC(DBMS_RANDOM.VALUE(0,365)),'J') from dual connect by level <= 1000000;
insert into TEST_A1000 SELECT SEQ_TESTA.Nextval,DBMS_RANDOM.STRING('A', 32),TRUNC(DBMS_RANDOM.VALUE(100, 1100)),TRUNC(DBMS_RANDOM.VALUE(0, 100)),to_date(2451984+TRUNC(DBMS_RANDOM.VALUE(0,365)),'J') from dual connect by level <= 10000000;

insert into TEST_AREA SELECT SEQ_TESTAREA.Nextval,DBMS_RANDOM.STRING('A', 32),TRUNC(DBMS_RANDOM.VALUE(0, 100)),DBMS_RANDOM.STRING('A', 1000) from dual connect by level <= 1100;
 
在表上面添加主鍵和索引:
alter table TEST_A1000
  add constraint PK_TEST primary key (ID)
  using index ;
-- Create/Recreate indexes 
create index IDX_NAME on TEST_A1000 (NAME);
分別分析下面的SQL語句:
SELECT COUNT(*) FROM TEST_A1000 a WHERE a.name IS NOT NULL;
--IS NOT NULL 走索引,IS NULL不走索引;
SELECT * FROM TEST_A1000 a WHERE a.name!='EnWYrMbvoWfBJSzoOevCfLQVAgIaNeSj'; ----不等於不走索引

 select * from TEST_A1000 where ID=10 or ID=20;   --不走索引
 select * from TEST_A1000 where ID IN (10,20,30);  --走索引,如果ID不加主鍵也不走
 select * from TEST_A1000 where NAME IN ('EnWYrMbvoWfBJSzoOevCfLQVAgIaNeSj');  --走索引
 select * from TEST_A1000 where ID BETWEEN 10 AND 30;       --走索引
 select * from TEST_A1000 where ID/30=100;               --走索引
 select * from TEST_A1000 where substr(NAME,0,3)='EnW';       --不走索引
 其他的圖片沒有一一貼出來,總之,不同的數據庫,不同的數據庫版本,不同的測試場景,可能結果都有所不同,不能道聽途說,不能人云亦云,絕知此事要躬行!

3,JOIN相關

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章